/// <summary> /// Determines the drag-and-drop operation which is beeing performed, which can be either None, Move or Copy. /// </summary> /// <param name="drgevent">DragEventArgs.</param> /// <returns>The current drag-and-drop operation.</returns> private DragDropEffects GetDragDropEffect(DragEventArgs drgevent) { const int CtrlKeyPlusLeftMouseButton = 9; // KeyState. DragDropEffects effect = DragDropEffects.None; // Retrieve the source control of the drag-and-drop operation. IDragDropSource src = drgevent.Data.GetData("IDragDropSource") as IDragDropSource; if (src != null && _dragDropGroup == src.DragDropGroup) { // The stuff being draged is compatible. if (src == this) { // Drag-and-drop happens within this control. if (_allowReorder && !Sorted) { effect = DragDropEffects.Move; } } else if (_isDragDropTarget) { // If only Copy is allowed then copy. If Copy and Move are allowed, then Move, unless the Ctrl-key is pressed. if (src.IsDragDropCopySource && (!src.IsDragDropMoveSource || drgevent.KeyState == CtrlKeyPlusLeftMouseButton)) { effect = DragDropEffects.Copy; } else if (src.IsDragDropMoveSource) { effect = DragDropEffects.Move; } } } return(effect); }
} // ReSharper restore UnusedMember.Global private static void SourceChanged(object sender, DependencyPropertyChangedEventArgs e) { DependencyObject Element = sender as DependencyObject; IDragDropSource NewSource = e.NewValue as IDragDropSource; IDragDropSource CurrentSource = e.OldValue as IDragDropSource; if (Element is UIElement || Element is ContentElement) { if (CurrentSource != null) { DragDropSourceAdapter Adapter; DragDrop.dragDropSources.TryGetValue(Element, out Adapter).DbC_Assure(isSuccess => isSuccess); DragDrop.dragDropSources.Remove(Element); Adapter?.Dispose(); } if (NewSource != null) { DragDropSourceAdapter Adapter = DragDropSourceAdapter.Create(NewSource, Element); DragDrop.dragDropSources.Add(Element, Adapter); } } else { throw new InvalidOperationException("Drag and Drop source can only be registered on UIElements and ContentElements"); } }
private DragDropSourceAdapter(IDragDropSource sourceHandler, DependencyObject source) { this.sourceHandler = sourceHandler; this.source = source; this.dragSourceHandler = DragDrop.GetDragDropUISourceHandler(source.GetType()).Create(source, this); System.Windows.DragDrop.AddGiveFeedbackHandler(this.source, DragDropSourceAdapter.GiveFeedback); System.Windows.DragDrop.AddQueryContinueDragHandler(this.source, DragDropSourceAdapter.QueryContinueDrag); }
static bool TryGetAsDragDropSource <T>( object obj, [MaybeNullWhen(false)] out IDragDropSource <T> source) { if (obj is ISourceList <T> sourceList) { source = new SourceListDragDropSource <T>(sourceList); return(true); } if (obj is ISourceListUiFunnel <T> funnel) { source = new SourceListDragDropSource <T>(funnel.SourceList); return(true); } if (obj is IDerivativeSelectedCollection <T> derivative) { if (derivative.OriginalList == null) { source = default; return(false); } else { source = new ListDragDropSource <T>(derivative.OriginalList); return(true); } } if (obj is IList <T> l) { source = new ListDragDropSource <T>(l); return(true); } source = default; return(false); }
protected override void OnDragDrop(DragEventArgs drgevent) { base.OnDragDrop(drgevent); _visualCue.Clear(); // Retrieve the drag item data. // Conditions have been testet in OnDragEnter and OnDragOver, so everything should be ok here. IDragDropSource src = drgevent.Data.GetData("IDragDropSource") as IDragDropSource; object[] srcItems = src.GetSelectedItems(); // If the list box is sorted, we don't know where the items will be inserted // and we will have troubles selecting the inserted items. So let's disable sorting here. bool sortedSave = Sorted; Sorted = false; // Insert at the currently hovered row. int row = DropIndex(drgevent.Y); int insertPoint = row; if (row >= Items.Count) { // Append items to the end. Items.AddRange(srcItems); } else { // Insert items before row. foreach (object item in srcItems) { Items.Insert(row++, item); } } // Remove all the selected items from the source, if moving. DropOperation operation; // Remembers the operation for the event we'll raise. if (drgevent.Effect == DragDropEffects.Move) { int adjustedInsertPoint = insertPoint; src.RemoveSelectedItems(ref adjustedInsertPoint); if (src == this) { // Items are being reordered. insertPoint = adjustedInsertPoint; operation = DropOperation.Reorder; } else { operation = DropOperation.MoveToHere; } } else { operation = DropOperation.CopyToHere; } // Adjust the selected items in the target. ClearSelected(); if (SelectionMode == SelectionMode.One) { // Select the first item inserted. SelectedIndex = insertPoint; } else if (SelectionMode != SelectionMode.None) { // Select the inserted items. for (int i = insertPoint; i < insertPoint + srcItems.Length; i++) { SetSelected(i, true); } } // Now that we've selected the inserted items, restore the "Sorted" property. Sorted = sortedSave; // Notify the target (this control). DroppedEventArgs e = new DroppedEventArgs { Operation = operation, Source = src, Target = this, DroppedItems = srcItems }; OnDropped(e); // Notify the source (the other control). if (operation != DropOperation.Reorder) { e = new DroppedEventArgs { Operation = operation == DropOperation.MoveToHere ? DropOperation.MoveFromHere : DropOperation.CopyFromHere, Source = src, Target = this, DroppedItems = srcItems }; src.OnDropped(e); } ClearSelected(); }
/// <summary> /// Registers a IDragDropSource to the manager /// </summary> /// <param name="dragDropSource"></param> public void RegisterDragDropSource(IDragDropSource dragDropSource) { if (dragDropSource == null) throw new ArgumentNullException("dragDropSource"); _sources.Add(dragDropSource); RegisterDraggable(dragDropSource); }
/// <summary> /// Generates drop targets when a drag operation is about to begin /// </summary> /// <param name="source"></param> protected void GenerateDropTargets(IDragDropSource source) { if (RootPanel.Children.Contains(_dropTargetLayout)) RemoveDropTargets(); _currentDragDropData = source.DragDropData; //source cannot be its own target during drag, so filter it out of the iteration, if exists //var dzs = _targets // .Where(o => !(source.Equals(o))); //.OrderBy(o => o.ZOrder) //.SelectMany(o => o.GetDropZones(source.DragDropData)); //NOTE: Using nested foreach instead of .SelectMany (commented out above) //NOTE: because .SelectMany seems to be making duplicate calls to o.GetDropZones(..) _targets .Where(o => !(source.Equals(o))) .ToObservable() .Subscribe(ddTarget => { // ReSharper disable ConvertToLambdaExpression ddTarget.GetDropZones(source.DragDropData) .ToObservable() .Subscribe(dropZone => { #if DEBUG //color up the hotspots during debug for visual reference if (ShowDropTargets) { var c = (byte)(200); ((Grid)dropZone.HotSpot).Background = new SolidColorBrush(Color.FromArgb(150, c, c, c)); } #endif //Canvas.SetZIndex(dz.DropZoneUI, dz.Source.ZOrder); dropZone.MouseLeftButtonUp += DropZoneMouseLeftButtonUp; _dropTargetLayout.Children.Add(dropZone.DropZoneUI); }); // ReSharper restore ConvertToLambdaExpression }); RootPanel.Children.Add(_dropTargetLayout); }
/// <summary> /// Unregisters a IDragDropSource from the manager /// </summary> /// <param name="dragDropSource"></param> public void UnRegisterDragDropSource(IDragDropSource dragDropSource) { if (dragDropSource == null) throw new ArgumentNullException("dragDropSource"); if (_sources.Contains(dragDropSource)) { _sources.Remove(dragDropSource); UnRegisterDraggable(dragDropSource); } }
public static DragDropSourceAdapter Create(IDragDropSource dragDropSource, DependencyObject dependencyObject) { return(new DragDropSourceAdapter(dragDropSource, dependencyObject)); }
// ReSharper disable UnusedMember.Global ///<summary> /// Registers a drag and drop source handler for a given UI element ///</summary> public static void SetSource(DependencyObject element, IDragDropSource source) { element.SetValue(DragDrop.SourceProperty, source); }