/// <summary> /// Retrieves the drop target of a drag event. /// </summary> /// <param name="args">Information about the drag event.</param> /// <returns>The drop target of a drag event.</returns> protected override ItemsControl GetDropTarget(SW.DragEventArgs args) { DependencyObject originalSource = (DependencyObject)args.OriginalSource; ItemsControl dropTarget = GetItemsControlAncestor(originalSource); if (dropTarget != null) { TreeViewItem targetItemContainer = GetItemContainerAncestor(dropTarget, (DependencyObject)args.OriginalSource); Orientation? orientation = GetOrientation(dropTarget); if (orientation != null && targetItemContainer != null) { Rect treeViewItemRect = GetTreeViewItemRectExcludingChildren(targetItemContainer); Point relativePoint = args.GetPosition(targetItemContainer); double thirdWidth = treeViewItemRect.Width / 3.0; double thirdHeight = treeViewItemRect.Height / 3.0; // If dragging into center third of item then the drop target // is the tree view item being hovered over. if ((orientation == Orientation.Horizontal && relativePoint.X > thirdWidth && relativePoint.X < (treeViewItemRect.Width - thirdWidth)) || (orientation == Orientation.Vertical && relativePoint.Y > thirdHeight && relativePoint.Y < (treeViewItemRect.Height - thirdHeight))) { return(targetItemContainer); } } } return(base.GetDropTarget(args)); }
/// <summary> /// Retrieves the original source of a new DragOver event. Attempts to /// determine the original source by finding the the deepest element /// in the tree that the mouse is over. /// </summary> /// <param name="args">Information about the drag event.</param> /// <returns>The original source of a new DragOver event.</returns> private static UIElement GetDragOverOriginalSource(SW.DragEventArgs args) { UIElement originalSource = args.OriginalSource as UIElement; // Use the previous original source and go to its root. // Note: this won't work if a popup appears on top of the // original source but it will work if the previous original source // is inside of a popup. UIElement rootVisual = originalSource.GetVisualAncestors().OfType <UIElement>().LastOrDefault(); if (rootVisual != null) { // If the original source disappears (ex. a popup disappears), // use the root visual. rootVisual = Application.Current.RootVisual; originalSource = FunctionalProgramming.TraverseBreadthFirst( rootVisual, node => node.GetVisualChildren().OfType <UIElement>(), node => new Rect(new Point(0, 0), node.GetSize()).Contains(args.GetPosition(node))) .LastOrDefault(); } return(originalSource); }