/// <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);
        }
Esempio n. 2
0
        }        // 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);
        }
Esempio n. 4
0
        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));
 }
Esempio n. 10
0
 // 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);
 }