private static void DragSource_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var elementPosition = e.GetPosition((IInputElement)sender); if ((sender is TabControl) && !HitTestUtilities.HitTest4Type <TabPanel>(sender, elementPosition)) { m_DragInfo = null; m_ClickSupressItem = null; return; } // If we prevented the control's default selection handling in DragSource_PreviewMouseLeftButtonDown // by setting 'e.Handled = true' and a drag was not initiated, manually set the selection here. var itemsControl = sender as ItemsControl; if (itemsControl != null && m_DragInfo != null && m_ClickSupressItem != null && m_ClickSupressItem == m_DragInfo.SourceItem) { if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) { itemsControl.SetItemSelected(m_DragInfo.SourceItem, false); } else if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0) { itemsControl.SetSelectedItem(m_DragInfo.SourceItem); } } m_DragInfo = null; m_ClickSupressItem = null; }
private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e) { m_DragInfo = null; // Ignore the click if clickCount != 1 or the user has clicked on a scrollbar. var elementPosition = e.GetPosition((IInputElement)sender); if (e.ClickCount != 1 || (sender as UIElement).IsDragSourceIgnored() || (e.Source as UIElement).IsDragSourceIgnored() || (e.OriginalSource as UIElement).IsDragSourceIgnored() || (sender is TabControl) && !HitTestUtilities.HitTest4Type <TabPanel>(sender, elementPosition) || HitTestUtilities.HitTest4Type <RangeBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <TextBoxBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <PasswordBox>(sender, elementPosition) || HitTestUtilities.HitTest4Type <ComboBox>(sender, elementPosition) || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypes(sender, elementPosition) || HitTestUtilities.IsNotPartOfSender(sender, e)) { return; } var dragInfo = new DragInfo(sender, e); if (dragInfo.VisualSource is ItemsControl control && control.CanSelectMultipleItems()) { control.Focus(); } if (dragInfo.VisualSourceItem == null) { return; } var dragHandler = TryGetDragHandler(dragInfo, sender as UIElement); if (!dragHandler.CanStartDrag(dragInfo)) { return; } // If the sender is a list box that allows multiple selections, ensure that clicking on an // already selected item does not change the selection, otherwise dragging multiple items // is made impossible. var itemsControl = sender as ItemsControl; if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0 && (Keyboard.Modifiers & ModifierKeys.Control) == 0 && dragInfo.VisualSourceItem != null && itemsControl != null && itemsControl.CanSelectMultipleItems()) { var selectedItems = itemsControl.GetSelectedItems().OfType <object>().ToList(); if (selectedItems.Count > 1 && selectedItems.Contains(dragInfo.SourceItem)) { m_ClickSupressItem = dragInfo.SourceItem; e.Handled = true; } } m_DragInfo = dragInfo; }
private static bool IsNonDraggableElement(object sender, Point elementPosition) { return(HitTestUtilities.HitTest4Type <RangeBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <TextBoxBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <PasswordBox>(sender, elementPosition) || HitTestUtilities.HitTest4Type <ComboBox>(sender, elementPosition) || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypes(sender, elementPosition) || HitTestUtilities.HitTest4Type <NoDrag>(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypes(sender, elementPosition)); }
private static void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // Ignore the click if clickCount != 1 or the user has clicked on a scrollbar. var elementPosition = e.GetPosition((IInputElement)sender); if (e.ClickCount != 1 || (sender as UIElement).IsDragSourceIgnored() || (e.Source as UIElement).IsDragSourceIgnored() || (e.OriginalSource as UIElement).IsDragSourceIgnored() || HitTestUtilities.HitTest4Type <RangeBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <ButtonBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <TextBoxBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <PasswordBox>(sender, elementPosition) || HitTestUtilities.HitTest4Type <ComboBox>(sender, elementPosition) || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypes(sender, elementPosition) || HitTestUtilities.IsNotPartOfSender(sender, e)) { m_DragInfo = null; return; } m_DragInfo = new DragInfo(sender, e); var dragHandler = TryGetDragHandler(m_DragInfo, sender as UIElement); if (!dragHandler.CanStartDrag(m_DragInfo)) { m_DragInfo = null; return; } // If the sender is a list box that allows multiple selections, ensure that clicking on an // already selected item does not change the selection, otherwise dragging multiple items // is made impossible. var itemsControl = sender as ItemsControl; if (m_DragInfo.VisualSourceItem != null && itemsControl != null && itemsControl.CanSelectMultipleItems()) { var selectedItems = itemsControl.GetSelectedItems().Cast <object>(); if (selectedItems.Count() > 1 && selectedItems.Contains(m_DragInfo.SourceItem)) { m_ClickSupressItem = m_DragInfo.SourceItem; e.Handled = true; } } }
/// <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; 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) { 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.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: {0}, {1}, {2}, Y={3}", this.InsertPosition, item, this.InsertIndex, currentYPos); } 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: InsPos={0}, InsIndex={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: {0}, item=NULL, {1}", this.InsertPosition, this.InsertIndex); } } else { this.VisualTargetItem = this.VisualTarget; } }
/// <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) { this.DragInfo = dragInfo; this.KeyStates = e.KeyStates; var dataFormat = dragInfo?.DataFormat; this.Data = dataFormat != null && e.Data.GetDataPresent(dataFormat.Name) ? e.Data.GetData(dataFormat.Name) : e.Data; 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; } } // try find ScrollViewer if (this.VisualTarget is TabControl) { var tabPanel = this.VisualTarget.GetVisualDescendent <TabPanel>(); this.TargetScrollViewer = tabPanel?.GetVisualAncestor <ScrollViewer>(); } else { this.TargetScrollViewer = this.VisualTarget?.GetVisualDescendent <ScrollViewer>(); } this.TargetScrollingMode = this.VisualTarget != null?DragDrop.GetDropScrollingMode(this.VisualTarget) : ScrollingMode.Both; // 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 = DropPosition.DirectlyOverElement(this.item, itemsControl); } 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 = DropPosition.DirectlyOverElement(this.item, itemsControl); } } 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.VisualTargetItem = item; this.TargetItem = itemParent.ItemContainerGenerator.ItemFromContainer(item); } var expandedTVItem = tvItem != null && tvItem.HasHeader && tvItem.HasItems && tvItem.IsExpanded; var itemRenderSize = expandedTVItem ? tvItem.GetHeaderSize() : item.RenderSize; if (this.VisualTargetOrientation == Orientation.Vertical) { var currentYPos = e.GetPosition(item).Y; var targetHeight = itemRenderSize.Height; var topGap = targetHeight * 0.25; var bottomGap = targetHeight * 0.75; if (currentYPos > targetHeight / 2) { if (expandedTVItem && (currentYPos < topGap || currentYPos > bottomGap)) { this.VisualTargetItem = tvItem.ItemContainerGenerator.ContainerFromIndex(0) as UIElement; this.TargetItem = this.VisualTargetItem != null?tvItem.ItemContainerGenerator.ItemFromContainer(this.VisualTargetItem) : null; this.TargetCollection = tvItem.ItemsSource ?? tvItem.Items; this.InsertIndex = 0; this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; } else { this.InsertIndex++; this.InsertPosition = RelativeInsertPosition.AfterTargetItem; } } else { this.InsertPosition = RelativeInsertPosition.BeforeTargetItem; } if (currentYPos > topGap && currentYPos < bottomGap) { 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; } }
private static void DropTarget_PreviewDragOver(object sender, DragEventArgs e) { var elementPosition = e.GetPosition((IInputElement)sender); if (HitTestUtilities.HitTest4Type <ScrollBar>(sender, elementPosition) || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypesOnDragOver(sender, elementPosition)) { e.Effects = DragDropEffects.None; e.Handled = true; return; } var dropInfo = new DropInfo(sender, e, m_DragInfo); var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement); var itemsControl = dropInfo.VisualTarget; dropHandler.DragOver(dropInfo); if (DragAdorner == null && m_DragInfo != null) { CreateDragAdorner(dropInfo); } if (DragAdorner != null) { var tempAdornerPos = e.GetPosition(DragAdorner.AdornedElement); if (tempAdornerPos.X >= 0 && tempAdornerPos.Y >= 0) { _adornerPos = tempAdornerPos; } // Fixed the flickering adorner - Size changes to zero 'randomly'...? if (DragAdorner.RenderSize.Width > 0 && DragAdorner.RenderSize.Height > 0) { _adornerSize = DragAdorner.RenderSize; } if (m_DragInfo != null) { // move the adorner var offsetX = _adornerSize.Width * -GetDragMouseAnchorPoint(m_DragInfo.VisualSource).X; var offsetY = _adornerSize.Height * -GetDragMouseAnchorPoint(m_DragInfo.VisualSource).Y; _adornerPos.Offset(offsetX, offsetY); var maxAdornerPosX = DragAdorner.AdornedElement.RenderSize.Width; var adornerPosRightX = (_adornerPos.X + _adornerSize.Width); if (adornerPosRightX > maxAdornerPosX) { _adornerPos.Offset(-adornerPosRightX + maxAdornerPosX, 0); } if (_adornerPos.Y < 0) { _adornerPos.Y = 0; } } DragAdorner.MousePosition = _adornerPos; DragAdorner.InvalidateVisual(); } // If the target is an ItemsControl then update the drop target adorner. if (itemsControl != null) { // Display the adorner in the control's ItemsPresenter. If there is no // ItemsPresenter provided by the style, try getting hold of a // ScrollContentPresenter and using that. var adornedElement = itemsControl is TabControl ? itemsControl.GetVisualDescendent <TabPanel>() : (itemsControl.GetVisualDescendent <ItemsPresenter>() ?? itemsControl.GetVisualDescendent <ScrollContentPresenter>() as UIElement ?? itemsControl); if (adornedElement != null) { if (dropInfo.DropTargetAdorner == null) { DropTargetAdorner = null; } else if (!dropInfo.DropTargetAdorner.IsInstanceOfType(DropTargetAdorner)) { DropTargetAdorner = DropTargetAdorner.Create(dropInfo.DropTargetAdorner, adornedElement); } if (DropTargetAdorner != null) { DropTargetAdorner.DropInfo = dropInfo; DropTargetAdorner.InvalidateVisual(); } } } // Set the drag effect adorner if there is one if (m_DragInfo != null && (EffectAdorner == null || EffectAdorner.Effects != dropInfo.Effects)) { CreateEffectAdorner(dropInfo); } if (EffectAdorner != null) { var adornerPos = e.GetPosition(EffectAdorner.AdornedElement); adornerPos.Offset(20, 20); EffectAdorner.MousePosition = adornerPos; EffectAdorner.InvalidateVisual(); } e.Effects = dropInfo.Effects; e.Handled = !dropInfo.NotHandled; if (!dropInfo.IsSameDragDropContextAsSource) { e.Effects = DragDropEffects.None; } Scroll(dropInfo.VisualTarget, e); }
private static void DropTargetOnDragOver(object sender, DragEventArgs e, EventType eventType) { var elementPosition = e.GetPosition((IInputElement)sender); var dragInfo = m_DragInfo; var dropInfo = new DropInfo(sender, e, dragInfo, eventType); var dropHandler = TryGetDropHandler(dropInfo, sender as UIElement); var itemsControl = dropInfo.VisualTarget; dropHandler.DragOver(dropInfo); if (DragAdorner == null && dragInfo != null) { CreateDragAdorner(dropInfo); } DragAdorner?.Move(e.GetPosition(DragAdorner.AdornedElement), dragInfo != null ? GetDragMouseAnchorPoint(dragInfo.VisualSource) : default(Point), ref _adornerMousePosition, ref _adornerSize); Scroll(dropInfo, e); if (HitTestUtilities.HitTest4Type <ScrollBar>(sender, elementPosition) || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) || HitTestUtilities.HitTest4DataGridTypesOnDragOver(sender, elementPosition)) { e.Effects = DragDropEffects.None; e.Handled = true; return; } // If the target is an ItemsControl then update the drop target adorner. if (itemsControl != null) { // Display the adorner in the control's ItemsPresenter. If there is no // ItemsPresenter provided by the style, try getting hold of a // ScrollContentPresenter and using that. UIElement adornedElement = null; if (itemsControl is TabControl) { adornedElement = itemsControl.GetVisualDescendent <TabPanel>(); } else if (itemsControl is DataGrid || (itemsControl as ListView)?.View is GridView) { adornedElement = itemsControl.GetVisualDescendent <ScrollContentPresenter>() as UIElement ?? itemsControl.GetVisualDescendent <ItemsPresenter>() as UIElement ?? itemsControl; } else { adornedElement = itemsControl.GetVisualDescendent <ItemsPresenter>() as UIElement ?? itemsControl.GetVisualDescendent <ScrollContentPresenter>() as UIElement ?? itemsControl; } if (adornedElement != null) { if (dropInfo.DropTargetAdorner == null) { DropTargetAdorner = null; } else if (!dropInfo.DropTargetAdorner.IsInstanceOfType(DropTargetAdorner)) { DropTargetAdorner = DropTargetAdorner.Create(dropInfo.DropTargetAdorner, adornedElement, dropInfo); } var adorner = DropTargetAdorner; if (adorner != null) { var adornerBrush = GetDropTargetAdornerBrush(dropInfo.VisualTarget); if (adornerBrush != null) { adorner.Pen.SetCurrentValue(Pen.BrushProperty, adornerBrush); } adorner.DropInfo = dropInfo; adorner.InvalidateVisual(); } } } // Set the drag effect adorner if there is one if (dragInfo != null && (EffectAdorner == null || EffectAdorner.Effects != dropInfo.Effects)) { CreateEffectAdorner(dropInfo); } EffectAdorner?.Move(e.GetPosition(EffectAdorner.AdornedElement), default(Point), ref _effectAdornerMousePosition, ref _effectAdornerSize); e.Effects = dropInfo.Effects; e.Handled = !dropInfo.NotHandled; if (!dropInfo.IsSameDragDropContextAsSource) { e.Effects = DragDropEffects.None; } }
/// <summary> /// Initializes a new instance of the DropInfo class. /// </summary> /// <param name="sender">The sender of the drop event.</param> /// <param name="e">The drag event arguments.</param> /// <param name="dragInfo">Information about the drag source, if the drag came from within the framework.</param> /// <param name="eventType">The type of the underlying event (tunneled or bubbled).</param> public DropInfo(object sender, DragEventArgs e, /*[CanBeNull]*/ IDragInfo dragInfo, EventType eventType) { this.DragInfo = dragInfo; this.KeyStates = e.KeyStates; this.EventType = eventType; var dataFormat = dragInfo?.DataFormat; this.Data = dataFormat != null && e.Data.GetDataPresent(dataFormat.Name) ? e.Data.GetData(dataFormat.Name) : e.Data; 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; } } // try find ScrollViewer var dropTargetScrollViewer = DragDrop.GetDropTargetScrollViewer(this.VisualTarget); if (dropTargetScrollViewer != null) { this.TargetScrollViewer = dropTargetScrollViewer; } else if (this.VisualTarget is TabControl) { var tabPanel = this.VisualTarget.GetVisualDescendent <TabPanel>(); this.TargetScrollViewer = tabPanel?.GetVisualAncestor <ScrollViewer>(); } else { this.TargetScrollViewer = this.VisualTarget?.GetVisualDescendent <ScrollViewer>(); } this.TargetScrollingMode = this.VisualTarget != null?DragDrop.GetDropScrollingMode(this.VisualTarget) : ScrollingMode.Both; // 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 itemsControl) { //System.Diagnostics.Debug.WriteLine(">>> Name = {0}", itemsControl.Name); // get item under the mouse var 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 = this.DropPosition.DirectlyOverElement(item, itemsControl); } if (item == null && this.TargetGroup is { IsBottomLevel : true })
private static bool IsDragHandle(object sender, Point elementPosition) { return(HitTestUtilities.HitTest4Type <DragHandle>(sender, elementPosition)); }