適当に見つけたプログラムをC#に直してみた企画。
今回もとにしたのはこれ。
ListBoxの項目をD&Dで入れ替え可能にするというもの。
ListBoxクラスを継承して作っているらしい。
class DragDropListBox : ListBox { /// <summary> /// ドラッグアンドドロップされるアイテムのデータ /// </summary> private struct DragDropItemData { public DragDropItemData(int index) { m_Index = index; } private int m_Index; public int Index { get { return m_Index; } } } public DragDropListBox() { this.AllowDrop = true; } // ドラッグアンドドロップの開始点 private Point mouseDownPoint; // ドラッグするアイテムのインデックス private int dragDropSourceItemIndex; /// <summary> /// MouseDown /// </summary> protected override void OnMouseDown(MouseEventArgs e) { if ( (e.Button & MouseButtons.Left) == MouseButtons.Left) { // ドラッグアンドドロップの開始点 mouseDownPoint = new Point(e.X, e.Y); dragDropSourceItemIndex = this.IndexFromPoint(e.X, e.Y); } else { mouseDownPoint = Point.Empty; dragDropSourceItemIndex = ListBox.NoMatches; } base.OnMouseDown(e); } /// <summary> /// MouseUp /// </summary> protected override void OnMouseUp(MouseEventArgs e) { mouseDownPoint = Point.Empty; base.OnMouseUp(e); } /// <summary> /// MouseMove /// </summary> protected override void OnMouseMove(MouseEventArgs e) { if ( (e.Button & MouseButtons.Left) == MouseButtons.Left) { // ドラッグアンドドロップの範囲にあるか否かをチェックする Rectangle dragBound = new Rectangle(e.X - SystemInformation.DragSize.Width / 2, e.Y - SystemInformation.DragSize.Height / 2, SystemInformation.DragSize.Width, SystemInformation.DragSize.Height); if (!dragBound.Contains(mouseDownPoint) && dragDropSourceItemIndex != ListBox.NoMatches) { // ドラッグアンドドロップ用のデータを作成 DragDropItemData itemData = new DragDropItemData(dragDropSourceItemIndex); // アイテムをドラッグアンドドロップする DragDropEffects effects = this.DoDragDrop(itemData, DragDropEffects.Move); } } base.OnMouseMove(e); } /// <summary> /// DragEnter /// </summary> protected override void OnDragEnter(DragEventArgs drgevent) { if (drgevent.Data.GetDataPresent(typeof(DragDropItemData))) { drgevent.Effect = DragDropEffects.Move; } else { drgevent.Effect = DragDropEffects.None; } base.OnDragEnter(drgevent); } /// <summary> /// DragDrop /// </summary> protected override void OnDragDrop(DragEventArgs drgevent) { if (drgevent.Data.GetDataPresent(typeof(DragDropItemData))) { // 入れ替え先のインデックス int targetIndex = this.IndexFromPoint(this.PointToClient(new Point(drgevent.X, drgevent.Y))); if (targetIndex == ListBox.NoMatches) { targetIndex = this.Items.Count - 1; } // ドラッグアンドドロップするアイテムのデータを取得 DragDropItemData itemData = (DragDropItemData)(drgevent.Data.GetData(typeof(DragDropItemData))); // アイテムを入れかえる Object temp = this.Items[itemData.Index]; this.Items[itemData.Index] = this.Items[targetIndex]; this.Items[targetIndex] = temp; // 入れ替えたアイテムを選択する this.SelectedItem = temp; } base.OnDragDrop(drgevent); } }
久しぶりのC#でbaseとかtypeofとか忘れてて焦った。
なぜこのコードを選んだかって、本当はListViewの並べ替えのプログラムを探していたのだけど……。