Пример #1
0
        private void DropTarget_PreviewDrop(object sender, DragEventArgs e)
        {
            var draggedItems    = e.Data.GetData(this.format.Name) as List <object>;
            var indiciesRemoved = new List <int>();

            if (draggedItems != null)
            {
                if ((e.Effects & DragDropEffects.Move) != 0)
                {
                    indiciesRemoved = DragDropUtilities.RemoveItemsFromItemsControl(this.sourceItemsControl, draggedItems);
                }

                // If we're dragging to the same list, adjust the insertion point to account for removed items.
                if (this.sourceItemsControl == this.targetItemsControl)
                {
                    int itemCountBeforeInsertionPoint = indiciesRemoved.Where(t => t < this.insertionIndex).Count();
                    this.insertionIndex -= itemCountBeforeInsertionPoint;
                }

                DragDropUtilities.InsertItemsInItemsControl(this.targetItemsControl, draggedItems, this.insertionIndex);

                this.RemoveDraggedAdorner();
                this.RemoveInsertionAdorner();
            }
            e.Handled = true;
        }
Пример #2
0
        // Drag = mouse down + move by a certain amount
        private void DragSource_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (this.draggedData != null)
            {
                // Only drag when user moved the mouse by a reasonable amount.
                if (DragDropUtilities.IsMovementBigEnough(this.initialMousePosition, e.GetPosition(this.topWindow)))
                {
                    var draggedItems = this.draggedData as List <object>;
                    var listView     = this.sourceItemsControl as ListView;
                    if (listView != null)
                    {
                        // Once the drag has started, we must re-select the originally dragged items. The initial click may have de-selected them.
                        listView.SelectedItems.Clear();

                        foreach (object item in draggedItems)
                        {
                            listView.SelectedItems.Add(item);
                        }
                    }

                    DataObject data;
                    try
                    {
                        data = new DataObject(this.format.Name, this.draggedData);
                    }
                    catch (COMException exception)
                    {
                        // Not sure what's going on here, can't reproduce. Hopefully this will allow the next drag operation to succeed.
                        Ioc.Get <IAppLogger>().LogError("Error during drag operation:" + Environment.NewLine + Environment.NewLine + exception);
                        this.draggedData = null;

                        return;
                    }

                    // Adding events to the window to make sure dragged adorner comes up when mouse is not over a drop target.
                    bool previousAllowDrop = this.topWindow.AllowDrop;
                    this.topWindow.AllowDrop  = true;
                    this.topWindow.DragEnter += this.TopWindow_DragEnter;
                    this.topWindow.DragOver  += this.TopWindow_DragOver;
                    this.topWindow.DragLeave += this.TopWindow_DragLeave;

                    DragDropEffects effects = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move);

                    // Without this call, there would be a bug in the following scenario: Click on a data item, and drag
                    // the mouse very fast outside of the window. When doing this really fast, for some reason I don't get
                    // the Window leave event, and the dragged adorner is left behind.
                    // With this call, the dragged adorner will disappear when we release the mouse outside of the window,
                    // which is when the DoDragDrop synchronous method returns.
                    this.RemoveDraggedAdorner();

                    this.topWindow.AllowDrop  = previousAllowDrop;
                    this.topWindow.DragEnter -= this.TopWindow_DragEnter;
                    this.topWindow.DragOver  -= this.TopWindow_DragOver;
                    this.topWindow.DragLeave -= this.TopWindow_DragLeave;

                    this.draggedData = null;
                }
            }
        }
Пример #3
0
        // DragSource

        private void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.sourceItemsControl = (ItemsControl)sender;
            var visual = e.OriginalSource as Visual;

            this.topWindow            = (Window)DragDropUtilities.FindAncestor(typeof(Window), this.sourceItemsControl);
            this.initialMousePosition = e.GetPosition(this.topWindow);

            this.sourceItemContainer = DragDropUtilities.GetItemContainer(this.sourceItemsControl, visual);
            if (this.sourceItemContainer != null)
            {
                object clickedItem = this.sourceItemContainer.DataContext;

                var itemsToDrag = new List <object>();

                var listView = this.sourceItemsControl as ListView;
                if (listView != null && listView.SelectedItems.Contains(clickedItem))
                {
                    // If we clicked on a selected item, do a multi-drag

                    // The selected items aren't always in order so we need to sort by index first.
                    var itemIndices = (from object selectedItem in listView.SelectedItems select this.sourceItemsControl.Items.IndexOf(selectedItem)).ToList();
                    itemIndices.Sort();

                    itemsToDrag.AddRange(itemIndices.Select(index => this.sourceItemsControl.Items[index]));
                }
                else
                {
                    // If we clicked on an unselected item, do a single drag
                    itemsToDrag.Add(clickedItem);
                }

                // Cull items that can't be dragged
                for (int i = itemsToDrag.Count - 1; i >= 0; i--)
                {
                    var dragData = itemsToDrag[i] as IDragItem;
                    if (dragData != null && !dragData.CanDrag)
                    {
                        itemsToDrag.RemoveAt(i);
                    }
                }

                if (itemsToDrag.Count > 0)
                {
                    this.draggedData = itemsToDrag;
                }
            }
        }
Пример #4
0
        // If the types of the dragged data and ItemsControl's source are compatible,
        // there are 3 situations to have into account when deciding the drop target:
        // 1. mouse is over an items container
        // 2. mouse is over the empty part of an ItemsControl, but ItemsControl is not empty
        // 3. mouse is over an empty ItemsControl.
        // The goal of this method is to decide on the values of the following properties:
        // targetItemContainer, insertionIndex and isInFirstHalf.
        private void DecideDropTarget(DragEventArgs e)
        {
            int targetItemsControlCount = this.targetItemsControl.Items.Count;
            var draggedItems            = e.Data.GetData(this.format.Name) as List <object>;

            this.targetItemContainer = null;

            if (draggedItems != null && this.IsDropDataTypeAllowed(draggedItems[0]))
            {
                if (targetItemsControlCount > 0)
                {
                    this.hasVerticalOrientation = DragDropUtilities.HasVerticalOrientation(this.targetItemsControl.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement);

                    // Hack, only works with vertical orientation lists. Original code assumed dragging to end of list if no
                    //  item is hovered over; this is incorrect.
                    for (int i = 0; i < targetItemsControlCount; i++)
                    {
                        FrameworkElement currentItemContainer = this.targetItemsControl.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;

                        if (currentItemContainer != null)
                        {
                            Point relativeDistanceFromItem = e.GetPosition(currentItemContainer);

                            if (relativeDistanceFromItem.Y < 0)
                            {
                                this.targetItemContainer = currentItemContainer;
                                break;
                            }

                            if (relativeDistanceFromItem.Y < currentItemContainer.ActualHeight)
                            {
                                this.targetItemContainer = currentItemContainer;
                                break;
                            }
                        }
                    }

                    if (this.targetItemContainer != null)
                    {
                        Point positionRelativeToItemContainer = e.GetPosition(this.targetItemContainer);
                        this.isInFirstHalf  = DragDropUtilities.IsInFirstHalf(this.targetItemContainer, positionRelativeToItemContainer, this.hasVerticalOrientation);
                        this.insertionIndex = this.targetItemsControl.ItemContainerGenerator.IndexFromContainer(this.targetItemContainer);

                        if (!this.isInFirstHalf)
                        {
                            this.insertionIndex++;
                        }
                    }
                    else
                    {
                        this.targetItemContainer = this.targetItemsControl.ItemContainerGenerator.ContainerFromIndex(targetItemsControlCount - 1) as FrameworkElement;
                        this.isInFirstHalf       = false;
                        this.insertionIndex      = targetItemsControlCount;
                    }

                    if (this.insertionIndex == 0 && !GetAllowDropAtTop(this.sourceItemsControl))
                    {
                        this.targetItemContainer = null;
                        this.insertionIndex      = -1;
                        e.Effects = DragDropEffects.None;
                    }
                }
                else
                {
                    this.insertionIndex = 0;
                }
            }
            else
            {
                this.insertionIndex = -1;
                e.Effects           = DragDropEffects.None;
            }
        }