// // OnDragLeave event handler. Updates the dragged node's ghost image's position. // protected override void OnDragLeave(EventArgs e) { base.OnDragLeave(e); DragHelper.ImageList_DragLeave(Handle); // Disable timer for scrolling dragged item _timer.Enabled = false; }
// // OnDragDrop event handler. Ends a node dragging // protected override void OnDragDrop(DragEventArgs drgevent) { base.OnDragDrop(drgevent); // Cancel if no node is being dragged if (_draggedNode == null) { return; } // Unlock updates DragHelper.ImageList_DragLeave(Handle); if (drgevent.Effect == DragDropEffects.None) { // Set drag node and temp drop node to null _draggedNode = null; _tempDropNode = null; // Disable scroll timer _timer.Enabled = false; return; } // Get drop node TreeNode dropNode = GetNodeAt(PointToClient(new Point(drgevent.X, drgevent.Y))); // Launch the feedback for the drag operation TreeViewNodeDragEventArgs evArgs = new TreeViewNodeDragEventArgs(TreeViewNodeDragEventType.DragEnd, TreeViewNodeDragEventBehavior.PlaceInside, _draggedNode, dropNode); if (DragOperation != null) { DragOperation(evArgs); // Cancel the operation if the user specified so if (evArgs.Cancel) { return; } } // If drop node isn't equal to drag node, add drag node as child of drop node if (_draggedNode != dropNode) { // Remove drag node from parent if (_draggedNode.Parent == null) { Nodes.Remove(_draggedNode); } else { _draggedNode.Parent.Nodes.Remove(_draggedNode); } // Place the dragged node before or after the target node depending on mouse position if (evArgs.EventBehavior == TreeViewNodeDragEventBehavior.PlaceBeforeOrAfterAuto) { // Get drop node Point mouseP = PointToClient(MousePosition); // Figure out whether the node should be added uder or over the pointed item by checking if the mouse is under or over the middle of the item evArgs.EventBehavior = mouseP.Y > dropNode.Bounds.Y + dropNode.Bounds.Height / 2 ? TreeViewNodeDragEventBehavior.PlaceAfter : TreeViewNodeDragEventBehavior.PlaceBefore; } // Place the dragged node before the target node if (evArgs.EventBehavior == TreeViewNodeDragEventBehavior.PlaceBefore) { // Add drag node before drop node if (dropNode.Parent != null) { dropNode.Parent.Nodes.Insert(dropNode.Index, _draggedNode); } else { Nodes.Insert(dropNode.Index, _draggedNode); } SelectedNode = _draggedNode; } // Place the dragged node after the target node if (evArgs.EventBehavior == TreeViewNodeDragEventBehavior.PlaceAfter) { // Add drag node after drop node if (dropNode.Parent != null) { dropNode.Parent.Nodes.Insert(dropNode.Index + 1, _draggedNode); } else { Nodes.Insert(dropNode.Index + 1, _draggedNode); } SelectedNode = _draggedNode; } // Place the dragged node inside the target node if (evArgs.EventBehavior == TreeViewNodeDragEventBehavior.PlaceInside) { // Add drag node to drop node dropNode.Nodes.Add(_draggedNode); dropNode.ExpandAll(); } // Launch the feedback for the drag operation evArgs = new TreeViewNodeDragEventArgs(TreeViewNodeDragEventType.AfterDragEnd, evArgs.EventBehavior, _draggedNode, dropNode); DragOperation?.Invoke(evArgs); // Set drag node and temp drop node to null _draggedNode = null; _tempDropNode = null; // Disable scroll timer _timer.Enabled = false; } }