TreeNodeのDrag&Dropを実装する TreeNodeのDrag&Dropを実装するには、結構実装することがあります。
具体的には、次のような手順を踏みます。
この例では、ツリーノードをドラッグ&ドラッグで移動できるようにします。
1. TreeViewのAllowDropプロパティをTrueに設定します。
2. ItemDragにドラッグを開始するコードを記述します。
3. DragEnterにドラッグがコントロール内に入った時の動作を記述します。
4. DragOverにドラッグ先のアイテムを展開するコードを記述します。
5. DragDropにドロップ後のコードを記述します。
private void treeViewMain_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
TreeNode targetNode = null;
TreeNode sourceNode = null;
if(e.Data.GetDataPresent(typeof(TreeNode)))
{
Point point = treeViewMain.PointToClient(new Point(e.X, e.Y));
targetNode = treeViewMain.GetNodeAt(point.X, point.Y);
sourceNode = e.Data.GetData(typeof(TreeNode)) as TreeNode;
int delta = treeViewMain.Height - point.Y;
if ((delta < treeViewMain.Height/2) && (delta > 0))
{
TreeNode tn = treeViewMain.GetNodeAt(point.X, point.Y);
if (tn.NextVisibleNode != null)
tn.NextVisibleNode.EnsureVisible();
}
if ((delta > treeViewMain.Height/2) && (delta < treeViewMain.Height))
{
TreeNode tn = treeViewMain.GetNodeAt(point.X, point.Y);
if (tn.PrevVisibleNode != null)
tn.PrevVisibleNode.EnsureVisible();
}
}
if(targetNode != null)
{
targetNode.Expand();
if(isTreeNodeMovable(sourceNode, targetNode))
{
e.Effect = DragDropEffects.Move;
}
else
{
e.Effect = DragDropEffects.None;
}
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void treeViewMain_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
if(e.Data.GetDataPresent(typeof(TreeNode)))
{
TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
Point point = treeViewMain.PointToClient(new Point(e.X, e.Y));
TreeNode targetNode = treeViewMain.GetNodeAt(point.X, point.Y);
if(isTreeNodeMovable(sourceNode, targetNode))
{
TreeNode dragNode = sourceNode;
treeViewMain.Nodes.Remove(sourceNode);
targetNode.Nodes.Insert(targetNode.Index+1, dragNode);
}
}
}
private bool isTreeNodeMovable(TreeNode source, TreeNode target)
{
if(target == null || source == null) return false;
if(target == source) return false;
if(target.Parent == source) return false;
// Target cannot be a source's child
if(isAncestor(target, source)) return false;
return true;
}
private bool isAncestor(TreeNode descendant, TreeNode ancestor)
{
TreeNode investigatedNode = descendant;
while(investigatedNode != null)
{
if(investigatedNode == ancestor) return true;
investigatedNode = investigatedNode.Parent;
}
return false;
}
private void treeViewMain_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
{
treeViewMain.DoDragDrop((TreeNode)e.Item, DragDropEffects.All);
}
private void treeViewMain_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
if(e.Data.GetDataPresent(typeof(TreeNode)) && sender.Equals(treeViewMain))
{
e.Effect = DragDropEffects.Move;
}
else
{
e.Effect = DragDropEffects.None;
}
}
目次に戻る
| Copyright(c) 2008 WoodenSoldier Software |
|