C# Tips


リストボックスでドラッグ&ドロップを使用する


リストボックスではItemDragイベントがありません。
ドラッグ&ドロップを実装するにはMouseDown, MouseUp, MouseMoveイベントを使用します。
ここでは、ListBoxDragDropクラスを使用して、実装をサポートします。
ドラッグ部分の処理を別クラスにしたり、delegateを使用したりすれば、さらに汎用性が増すでしょう。
// ListtBoxDragDropクラス 

using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;

namespace GuiSupport
{
	public class ListBoxDragDrop
	{
		private Hashtable listBoxTable;

		public ListBoxDragDrop()
		{
			listBoxTable = new Hashtable();
		}

		public void MouseDown(ListBox listBox, System.Windows.Forms.MouseEventArgs e)
		{
			if(e.Button == MouseButtons.Left)
			{
				if(listBox.IndexFromPoint(e.X, e.Y) >= 0)
				{
					StoreData(listBox, new Point(e.X, e.Y));
				}
			}
			else
			{
				StoreData(listBox, Point.Empty);
			}
		}

		public void MouseUp(ListBox listBox)
		{
			StoreData(listBox, Point.Empty);
		}

		public void MouseMove(ListBox listBox, System.Windows.Forms.MouseEventArgs e)
		{
			Point mouseDownPoint = LoadData(listBox);

			if (mouseDownPoint != Point.Empty)
			{
				if (CanDragStart(mouseDownPoint, new Point(e.X, e.Y)) == true)
				{
					int itemIndex = listBox.IndexFromPoint(mouseDownPoint);

					if (itemIndex >= 0)
					{
						// ここにドラッグする処理を書く
						string item = listBox.Items[itemIndex].ToString();

						if(item != null)
						{
							listBox.DoDragDrop(item, DragDropEffects.All);
						}
						//ここまで

						StoreData(listBox, Point.Empty);
					}
				}
			}
		}

		private bool CanDragStart(Point mouseDownPoint, Point currentPoint)
		{
			Rectangle region = new Rectangle(
				mouseDownPoint.X - SystemInformation.DragSize.Width / 2,
				mouseDownPoint.Y - SystemInformation.DragSize.Height / 2,
				SystemInformation.DragSize.Width,
				SystemInformation.DragSize.Height);

			if(region.Contains(currentPoint.X, currentPoint.Y) == false)
			{
				return true;
			}

			return false;
		}

		private void StoreData(ListBox listBox, Point point)
		{
			if(listBoxTable.ContainsKey(listBox))
			{
				listBoxTable[listBox] = point;
			}
			else
			{
				listBoxTable.Add(listBox, point);
			}
		}

		private Point LoadData(ListBox listBox)
		{
			if(listBoxTable.ContainsKey(listBox))
			{
				return (Point)listBoxTable[listBox];
			}

			return Point.Empty;
		}
	}
}

// ListBoxDragDropを使うには

private void listBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
	listBoxDragDrop.MouseDown((ListBox)sender, e);
}

private void listBox_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
	listBoxDragDrop.MouseUp((ListBox)sender);
}

private void listBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
	listBoxDragDrop.MouseMove((ListBox)sender, e);
}


目次に戻る
Copyright(c) 2008 WoodenSoldier Software