Drag & Drop im Treeview

Um in einer normalen "Winforms" - Anwendung Drag & Drop anzubieten müssen spezielle Events abgefangen und verarbeitet werden.

Gehen wir für ein Beispiel von einem Treeview aus in dem Elemente, z.B. Ordner, verschoben werden können.

Vorbereitung des Baumes:

  • Property "AllowDrop" auf true setzten

  • Eventhandler für "ItemDrag"

  • Eventhandler für "DragOver"

  • Eventhandler für "DragDrop"



Im Handler "ItemDrag" wird bestimmt welche Elemente gezogen werden können.
In unserem Beispiel sind das alle.
Das Ziehen wird dann wie folgt aktiviert:
1 private void tvwMainItemDrag(object sender, ItemDragEventArgs e)
2 {
3 DoDragDrop(e.Item, DragDropEffects.Move);
4 }


Nun erhalten wir beim Ziehen des Elements über unseren Treeview - Bereich permanent das Event "DragOver":

 1 private void tvwMainDragOver(object sender, DragEventArgse)
2 {
3 //Grundsätzliches Verweigern des Drop
4 e.Effect = DragDropEffects.None;
5
6 //Typ für den ein Drop erlaubt ist prüfen, alle anderen abweisen
7 if (!(e.Data.GetDataPresent(typeof(TreeNode)))) return;
8
9 //Es ist auch möglich Texte und Bilder etc. aus anderen Anwendungen zu akzeptieren
10 TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
11
12 }


Optisch wird jetzt über den Move-Cursor signalisiert das die gezogene TreeNode hier abgelegt werden kann.

Beim "loslassen" wird dann das Event "DragDrop" gefeuert. Auch hier muss entsprechend reagiert werden:


 1 private void tvwMainDragDrop(object sender, DragEventArgse)
2 {
3 //Typ für den ein Drop erlaubt ist prüfen, alle anderen abweisen
4 if (!(e.Data.GetDataPresent(typeof(TreeNode)))) return;
5
6 TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
7 //aus dem Baum herauslösen
8 sourceNode.Remove();
9
10 //Ziel feststellen
11 Point pt = tvwMain.PointToClient(new Point(e.X, e.Y));
12 TreeNode targetNode = (TreeNode)tvwMain.GetNodeAt(pt);
13
14 //Am Ziel einfügen
15 targetNode.Nodes.Add(sourceNode);
16
17 }


Dies ist nur ein einfaches Beispiel, welches durch diverse Logik erweitert werden muaa. Nötig ist zum Beispiel eine Prüfung ob die targetNode eine ChildNode der sourceNode ist (damit der Vater nicht zum Kind des Kindes wird und damit die Familie auslöscht).

Eine Prüfung sollte dafür schon im Event DragOver stattfinden und könnte so aussehen:
1 if (targetNode.FullPath.Contains(sourceNode.FullPath)) e.Effect = DragDropEffects.None;

Keine Kommentare: