// // 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; } }
// // OnDragDrop event handler. Ends a node dragging // protected override void OnDragDrop(DragEventArgs drgevent) { base.OnDragDrop(drgevent); // Cancel if no node is being dragged if (_draggedItems == null) { _timer.Start(); return; } if (drgevent.Effect == DragDropEffects.None) { // Set drag node and temp drop node to null _draggedItems = null; _tempDropItem = null; // Disable scroll timer _timer.Enabled = false; _timer.Start(); return; } if (InsertionMark.Index == -1) { _timer.Start(); return; } // Get drop item ListViewItem dropItem = Items[InsertionMark.Index]; // Launch the feedback for the drag operation ListViewItemDragEventArgs evArgs = new ListViewItemDragEventArgs(ListViewItemDragEventType.DragEnd, ListViewItemDragEventBehavior.PlaceBeforeOrAfterAuto, _draggedItems, dropItem); if (DragOperation != null) { DragOperation(evArgs); // Cancel the operation if the user specified so if (evArgs.Cancel) { _timer.Start(); return; } } // If drop node isn't equal to drag node, add drag node as child of drop node if (_draggedItems[0] != dropItem) { int index = InsertionMark.Index; SelectedItems.Clear(); foreach (ListViewItem item in _draggedItems) { Items.Remove(item); Items.Add(item); item.Selected = true; } // Deal with a bug from the framework that adds all items to the end even though you insert // them at other indexes by also pushing all items after the current selection to the end for (int i = index; i < Items.Count - SelectedItems.Count; i++) { ListViewItem item = Items[index]; Items.Remove(item); Items.Add(item); } // Launch the feedback for the drag operation evArgs = new ListViewItemDragEventArgs(ListViewItemDragEventType.AfterDragEnd, evArgs.EventBehavior, _draggedItems, dropItem); DragOperation?.Invoke(evArgs); // Set drag node and temp drop node to null _draggedItems = null; _tempDropItem = null; // Disable scroll timer _timer.Enabled = false; } _timer.Start(); }