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); } // Moves DragAdorner following with mouse point 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.FindVisualChild <TabPanel>(); } else if (itemsControl is DataGrid || (itemsControl as ListView)?.View is GridView) { adornedElement = itemsControl.FindVisualChild <ScrollContentPresenter>() ?? itemsControl.FindVisualChild <ItemsPresenter>() ?? itemsControl; } else { adornedElement = itemsControl.FindVisualChild <ItemsPresenter>() ?? itemsControl.FindVisualChild <ScrollContentPresenter>() ?? 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.Brush = 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> /// Set base drag info when mouse left button down /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e) { m_DragInfo = null; // Gets the position of the mouse relative to source control var elementPosition = e.GetPosition((IInputElement)sender); // Ignore the click if clickCount != 1 or the user has clicked on a scrollbar or the control while editing. if (e.ClickCount != 1 || (sender as UIElement).IsDragSourceIgnored() || (e.Source as UIElement).IsDragSourceIgnored() || (e.OriginalSource as UIElement).IsDragSourceIgnored() // Ignore TabControl's content presenter || (sender is TabControl) && !HitTestUtilities.HitTest4Type <TabPanel>(sender, elementPosition) // Ignore scroll bar || HitTestUtilities.HitTest4Type <RangeBase>(sender, elementPosition) // Ignore the control while editing. || HitTestUtilities.HitTest4Type <TextBoxBase>(sender, elementPosition) || HitTestUtilities.HitTest4Type <PasswordBox>(sender, elementPosition) || HitTestUtilities.HitTest4Type <ComboBox>(sender, elementPosition) // Ignore grid column header || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition) // Ignore user reordering DataGrid columns and drag row header gripper to chang row header height || 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(didn't click a shift key or control key at the same time), // otherwise dragging multiple items is made impossible. if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0 && (Keyboard.Modifiers & ModifierKeys.Control) == 0 && dragInfo.VisualSourceItem != null && sender is ItemsControl itemsControl && itemsControl.CanSelectMultipleItems()) { var selectedItems = itemsControl.GetSelectedItems().OfType <object>().ToList(); // we haven't pressed control key and shift key, set clicked current item if (selectedItems.Count > 1 && selectedItems.Contains(dragInfo.SourceItem)) { m_ClickSupressItem = dragInfo.SourceItem; e.Handled = true; } } m_DragInfo = dragInfo; }