/// <summary> /// Initializes a new instance of the DropInfo class. /// </summary> /// /// <param name="sender"> /// The sender of the drag event. /// </param> /// /// <param name="e"> /// The drag event. /// </param> /// /// <param name="dragInfo"> /// Information about the source of the drag, if the drag came from within the framework. /// </param> public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo) { var dataFormat = DragDrop.DataFormat.Name; this.Data = (e.Data.GetDataPresent(dataFormat)) ? e.Data.GetData(dataFormat) : e.Data; this.DragInfo = dragInfo; this.KeyStates = e.KeyStates; this.VisualTarget = sender as UIElement; // if there is no drop target, find another if (!this.VisualTarget.IsDropTarget()) { // try to find next element var element = this.VisualTarget.TryGetNextAncestorDropTargetElement(); if (element != null) { this.VisualTarget = element; } } // visual target can be null, so give us a point... this.DropPosition = this.VisualTarget != null ? e.GetPosition(this.VisualTarget) : new Point(); if (this.VisualTarget is TabControl) { if (!HitTestUtilities.HitTest4Type<TabPanel>(this.VisualTarget, this.DropPosition)) { return; } } if (this.VisualTarget is ItemsControl) { var itemsControl = (ItemsControl)this.VisualTarget; //System.Diagnostics.Debug.WriteLine(">>> Name = {0}", itemsControl.Name); // get item under the mouse item = itemsControl.GetItemContainerAt(this.DropPosition); var directlyOverItem = item != null; this.TargetGroup = itemsControl.FindGroup(this.DropPosition); this.VisualTargetOrientation = itemsControl.GetItemsPanelOrientation(); this.VisualTargetFlowDirection = itemsControl.GetItemsPanelFlowDirection(); if (item == null) { // ok, no item found, so maybe we can found an item at top, left, right or bottom item = itemsControl.GetItemContainerAt(this.DropPosition, this.VisualTargetOrientation); directlyOverItem = false; } if (item == null && this.TargetGroup != null && this.TargetGroup.IsBottomLevel) { var itemData = this.TargetGroup.Items.FirstOrDefault(); if (itemData != null) { item = itemsControl.ItemContainerGenerator.ContainerFromItem(itemData) as UIElement; directlyOverItem = false; } } if (item != null) { itemParent = ItemsControl.ItemsControlFromItemContainer(item); this.VisualTargetOrientation = itemParent.GetItemsPanelOrientation(); this.VisualTargetFlowDirection = itemParent.GetItemsPanelFlowDirection(); this.InsertIndex = itemParent.ItemContainerGenerator.IndexFromContainer(item); this.TargetCollection = itemParent.ItemsSource ?? itemParent.Items; var tvItem = item as TreeViewItem; if (directlyOverItem || tvItem != null) { this.TargetItem = itemParent.ItemContainerGenerator.ItemFromContainer(item); this.VisualTargetItem = item; } var itemRenderSize = item.RenderSize; if (this.VisualTargetOrientation == Orientation.Vertical) { var currentYPos = e.GetPosition(item).Y; var targetHeight = itemRenderSize.Height; if (currentYPos > targetHeight / 2) { this.InsertIndex++; this.InsertPosition = RelativeInsertPosition.AfterTargetItem; } else { this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; } if (currentYPos > targetHeight * 0.25 && currentYPos < targetHeight * 0.75) { if (tvItem != null) { this.TargetCollection = tvItem.ItemsSource ?? tvItem.Items; this.InsertIndex = this.TargetCollection != null ? this.TargetCollection.OfType<object>().Count() : 0; } this.InsertPosition |= RelativeInsertPosition.TargetItemCenter; } //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, idx={1}, Y={2}, Item={3}", this.InsertPosition, this.InsertIndex, currentYPos, item); } else { var currentXPos = e.GetPosition(item).X; var targetWidth = itemRenderSize.Width; if (this.VisualTargetFlowDirection == FlowDirection.RightToLeft) { if (currentXPos > targetWidth / 2) { this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; } else { this.InsertIndex++; this.InsertPosition = RelativeInsertPosition.AfterTargetItem; } } else if (this.VisualTargetFlowDirection == FlowDirection.LeftToRight) { if (currentXPos > targetWidth / 2) { this.InsertIndex++; this.InsertPosition = RelativeInsertPosition.AfterTargetItem; } else { this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; } } if (currentXPos > targetWidth * 0.25 && currentXPos < targetWidth * 0.75) { if (tvItem != null) { this.TargetCollection = tvItem.ItemsSource ?? tvItem.Items; this.InsertIndex = this.TargetCollection != null ? this.TargetCollection.OfType<object>().Count() : 0; } this.InsertPosition |= RelativeInsertPosition.TargetItemCenter; } //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, idx={1}, X={2}, Item={3}", this.InsertPosition, this.InsertIndex, currentXPos, item); } } else { this.TargetCollection = itemsControl.ItemsSource ?? itemsControl.Items; this.InsertIndex = itemsControl.Items.Count; //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, item=NULL, idx={1}", this.InsertPosition, this.InsertIndex); } } else { this.VisualTargetItem = this.VisualTarget; } }