private bool CanExecuteDrag(DragCommandParameter parameter) { // Determine the data that is dragged and store it in parameter.Tag. // If a ContentControl is dragged, use ContentControl.Content. var contentControl = AssociatedObject as ContentControl; if (contentControl != null) { // The dragged element is not within an ItemsControl. // --> Select the data-context. parameter.Tag = contentControl.Content; return(true); } // If an item of an ItemsControl is dragged, use ItemContainer.DataContext. var itemsControl = AssociatedObject as ItemsControl; if (itemsControl != null) { // The dragged element is within an ItemsControl. // --> Select the clicked item. var visual = parameter.HitObject as Visual; Debug.Assert(visual != null, "HitObject should always be set."); var itemContainer = itemsControl.ContainerFromElement(visual) as FrameworkElement; if (itemContainer != null) { parameter.Tag = itemContainer.DataContext; return(true); } } return(false); }
private void DisableDrag() { // Abort current drag operation. _dragCommandParameter = null; // Unregister event handlers. AssociatedObject.PreviewMouseLeftButtonDown -= OnPreviewMouseLeftButtonDown; AssociatedObject.MouseLeftButtonDown -= OnMouseLeftButtonDown; AssociatedObject.PreviewMouseLeftButtonUp -= OnPreviewMouseLeftButtonUp; AssociatedObject.PreviewMouseMove -= OnPreviewMouseMove; }
private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs eventArgs) { if (eventArgs.Handled || !UsePreviewEvent) { return; } _dragCommandParameter = new DragCommandParameter { AssociatedObject = AssociatedObject, HitObject = eventArgs.OriginalSource as DependencyObject, MousePosition = eventArgs.GetPosition(AssociatedObject), }; OnMouseLeftButtonDown(eventArgs); }
private void OnPreviewMouseMove(object sender, MouseEventArgs eventArgs) { if (eventArgs.Handled) { return; } if (_dragCommandParameter == null) { return; } // Avoid reentrance if (_inDragDrop) { // Not sure why this happens. It can happen when dragging from a Button... return; } // Only start drag-and-drop when user moved the mouse by a reasonable amount. if (!ExceedsMinimumDragDistance(_dragCommandParameter.MousePosition, eventArgs.GetPosition(AssociatedObject))) { return; } _inDragDrop = true; // The user wants to drag something. try { var dragCommand = DragCommand ?? DefaultDragCommand; if (dragCommand.CanExecute(_dragCommandParameter)) { // Call DragCommand to start the drag-and-drop operation. dragCommand.Execute(_dragCommandParameter); eventArgs.Handled = true; } } finally { _inDragDrop = false; _dragCommandParameter = null; } }
private void OnMouseLeftButtonDown(MouseButtonEventArgs eventArgs) { _dragCommandParameter = new DragCommandParameter { AssociatedObject = AssociatedObject, HitObject = eventArgs.OriginalSource as DependencyObject, MousePosition = eventArgs.GetPosition(AssociatedObject), }; // Call DragCommand.CanExecute() and let the view model decide whether // dragging is possible. The drag-and-drop starts in the mouse move // event when the user moves the mouse by a significant distance. var dragCommand = DragCommand ?? DefaultDragCommand; if (!dragCommand.CanExecute(_dragCommandParameter)) { _dragCommandParameter = null; } }
private void ExecuteDrag(DragCommandParameter parameter) { // The data was determined in CanExecuteDrag and stored in the Tag. var data = parameter.Tag; if (data == null) { return; } // Wrap data in IDataObject. var dataObject = SetData(data); _sourceUpdated = false; // Execute drag-and-drop. var effect = DragDrop.DoDragDrop(parameter.AssociatedObject, dataObject, DefaultEffects); // Update source if not already handled by DropCommand. if ((effect & DragDropEffects.Move) != 0 && !_sourceUpdated) { // Remove data from source. var contentControl = parameter.AssociatedObject as ContentControl; var itemsControl = parameter.AssociatedObject as ItemsControl; if (contentControl != null) { // Source is a ContentControl. // --> Remove content. contentControl.Content = null; } else if (itemsControl != null) { // Source is an ItemsControl. // --> Remove item. RemoveItemFromItemsControl(itemsControl, data); } } }
private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs eventArgs) { // Cancel drag operation. _dragCommandParameter = null; }