Esempio n. 1
0
        void OnDropped(PointerRoutedEventArgs e)
#endif
        {
            _popup.IsOpen = false;

            //We no longer have use for the popup
            _popup.Child = null;
            _popup       = null;

            // Prepare the event arguments:
            Selection           selection           = new Selection(_sourceItemContainer);
            SelectionCollection selectionCollection = SelectionCollection.ToSelectionCollection(selection);

            // Get the DragDropTarget element that is under the pointer, if any:
            TItemContainerType targetItemContainer;
            DragDropTarget <TItemsControlType, TItemContainerType> dragDropTargetUnderPointer = GetDragDropTargetUnderPointer(_pointerX, _pointerY, out targetItemContainer);

            if (dragDropTargetUnderPointer != null)
            {
                //---------------------------------
                // IF A DROP TARGET IS FOUND
                //---------------------------------

                // Check if drop is allowed:
                if (dragDropTargetUnderPointer.AllowDrop && !_isDragCancelled)
                {
                    TItemsControlType targetContainer = (TItemsControlType)dragDropTargetUnderPointer.Content; // Note: a "container" is for example a Panel in case of PanekDragDropTarget.

                    // Check if we are dropping on the source element itself (ie. from the source to the placeholder that we put in place of the source) (cf. "ItemDropOnSource" event):
                    if (ContainerFromIndex(targetContainer, _indexOfSourceContainerWithinItemsControl) == _sourcePlaceholder)
                    {
                        //---------------------------------
                        // IF WE ARE DROPPING THE SOURCE ON ITSELF
                        //---------------------------------

                        // Put the dragged element back to where it was:
                        PutSourceBackToOriginalPlace();

                        //Raise the "ItemDroppedOnSource" Event
                        if (dragDropTargetUnderPointer.ItemDroppedOnSource != null)
                        {
                            // Prepare the event args:
                            DataObject dataObject = new DataObject();
                            dataObject.SetData("ItemDragEventArgs", new ItemDragEventArgs(selectionCollection));

#if !(BRIDGE && MIGRATION)
                            dragDropTargetUnderPointer.ItemDroppedOnSource(dragDropTargetUnderPointer, new MS.DragEventArgs(dataObject, e));
#endif
                        }
                    }
                    //else we drop on another DragDropTarget
                    else
                    {
                        //---------------------------------
                        // IF WE ARE DROPPING ON ANOTHER DRAGDROPTARGET
                        //---------------------------------

                        // Remove the temporary placeholder (see the comment where the placeholder is defined):
                        this.RemoveItemAtIndex(_sourceItemsControl, _indexOfSourceContainerWithinItemsControl);

                        // Raise the Drop event:
                        if (dragDropTargetUnderPointer.Drop != null)
                        {
                            // Prepare the event args:
                            DataObject dataObject = new DataObject();
                            dataObject.SetData("ItemDragEventArgs", new ItemDragEventArgs(selectionCollection));

                            // Raise the Drop event:
#if !(BRIDGE && MIGRATION)
                            dragDropTargetUnderPointer.Drop(dragDropTargetUnderPointer, new MS.DragEventArgs(dataObject, e));
#endif
                        }

                        // Put the source into the target:
                        dragDropTargetUnderPointer.AddItem((TItemsControlType)dragDropTargetUnderPointer.Content, _sourceItemContainer);
                    }
                }
                //Can't drop so we put what was in the popup back in the content
                else
                {
                    // Put the dragged element back to where it was:
                    PutSourceBackToOriginalPlace();
                }
            }
            //not a DragDropTarget under the pointer so we put what was in the popup back in the content
            else
            {
                // Put the dragged element back to where it was:
                PutSourceBackToOriginalPlace();
            }

            // Raise the "ItemDragCompleted" event:
            if (ItemDragCompleted != null)
            {
                ItemDragCompleted(this, new ItemDragEventArgs(selectionCollection));
            }
        }
Esempio n. 2
0
        private void DragDropTarget_PointerPressed(object sender, PointerRoutedEventArgs e)
#endif
        {
            //----------------------------------
            // DRAG OPERATION STARTS HERE
            //----------------------------------

            // Prevent the PointerPressed event from bubbling up so that if there are two nested DragDropTargets, only the inner one will be dragged:
            e.Handled = true;

            // We verify that drag operation is not taking place, which can lead a case if we missed the pointer released event due to a glitch such as moving the mouse outside the browser and releasing
            if (!_isPointerCaptured)
            {
                // Reset some variables:
                _isDragCancelled = false;
                _previousdragDropTargetUnderPointer = null;

                // Remember the current pointer position:
#if MIGRATION
                _pointerX = e.GetPosition(null).X;
                _pointerY = e.GetPosition(null).Y;
#else
                _pointerX = e.GetCurrentPoint(null).Position.X;
                _pointerY = e.GetCurrentPoint(null).Position.Y;
#endif
                // Get the source DragDropTarget element that is under the pointer, if any:
                DragDropTarget <TItemsControlType, TItemContainerType> sourceDragDropTarget = GetDragDropTargetUnderPointer(_pointerX, _pointerY, out _sourceItemContainer);
                if (sourceDragDropTarget != this)
                {
                    throw new Exception("The DragDropTarget is not supposed to support dragging an outer DragDropTarget in case of nested DragDropTargets.");
                }

                // We do something only if the source exists (ie. if an item was found under the pointer):
                if (_sourceItemContainer != null)
                {
                    // Get a reference to the ItemsControl:
                    _sourceItemsControl = (TItemsControlType)this.Content; // Note: there is no risk of InvalidCastException because the type has been tested before, and the derived class (PanelDragDropTarget) also verifies the type in the "OnContentChanged" method.

                    // Capture the pointer so that when dragged outside the DragDropPanel, we can still get its position:
    #if MIGRATION
                    this.CaptureMouse();
    #else
                    this.CapturePointer(e.Pointer);
    #endif
                    // Remember that the pointer is currently captured:
                    _isPointerCaptured = true;
                    _capturedPointer   = e.Pointer;

                    //Size of the content
                    double height;
                    double width;
                    if (_sourceItemContainer is FrameworkElement)
                    {
                        Size actualSize = (_sourceItemContainer as FrameworkElement).INTERNAL_GetActualWidthAndHeight();
                        height = actualSize.Height;
                        width  = actualSize.Width;
                    }
                    else
                    {
                        height = double.NaN;
                        width  = double.NaN;
                    }

                    // Prepare the arguments of the "ItemDragStarting" event:
                    Selection           selection                 = new Selection(_sourceItemContainer);
                    SelectionCollection selectionCollection       = SelectionCollection.ToSelectionCollection(selection);
                    ItemDragEventArgs   itemDragStartingEventArgs = new ItemDragEventArgs(selectionCollection);

                    // Raise the "ItemDragStarting" event:
                    if (ItemDragStarting != null)
                    {
                        ItemDragStarting(this, itemDragStartingEventArgs);
                    }

                    // Show the popup, unless the user has cancelled the drag operation:
                    if (itemDragStartingEventArgs.Handled && itemDragStartingEventArgs.Cancel)
                    {
                        //----------------------------------
                        // CANCELLED BY USER
                        //----------------------------------

                        if (_isPointerCaptured)
                        {
                            // Stop capturing the pointer:
                            _isPointerCaptured = false;

#if MIGRATION
                            this.ReleaseMouseCapture();
#else
                            this.ReleasePointerCapture(_capturedPointer);
#endif
                        }
                    }
                    else
                    {
                        //----------------------------------
                        // SHOW POPUP
                        //----------------------------------

                        // Put a placeholder in place of the source that will occupy the same space. This is useful to: 1) let the user drop over the source itself (cf. "ItemDroppedOnSource" event), and 2) prevent the other elements from being displaced during the drag operation.
                        RemoveSourceAndPutTransparentPlaceholderInPlace(height, width);

                        // Put the source into a popup:
                        StackPanel stackPanelInPopUp = GeneratePopupContent(_sourceItemContainer, out _iconStop, out _iconArrow);
                        this._popup = new Popup()
                        {
                            Child = stackPanelInPopUp,
                            HorizontalAlignment        = HorizontalAlignment.Left,
                            VerticalAlignment          = VerticalAlignment.Top,
                            HorizontalContentAlignment = HorizontalAlignment.Left,
                            VerticalContentAlignment   = VerticalAlignment.Top,
                            IsHitTestVisible           = false
                        };

                        // Set the popup position:
                        this._popup.HorizontalOffset = this._pointerX;
                        this._popup.VerticalOffset   = this._pointerY;

                        // Show the popup:
                        this._popup.IsOpen = true;
                    }
                }
            }
        }
Esempio n. 3
0
        private void MovePopupAndRaiseEvents(double horizontalChange, double verticalChange)
        {
#if !(BRIDGE && MIGRATION)
            if (_popup != null)
            {
                //popup moving with the pointer
                _popup.HorizontalOffset += horizontalChange;
                _popup.VerticalOffset   += verticalChange;
            }

            // Prepare the "DragEventArgs" to pass to the raised events:
            Selection           selection           = new Selection(_sourceItemContainer);
            SelectionCollection selectionCollection = SelectionCollection.ToSelectionCollection(selection);
            DataObject          dataObject          = new DataObject();
            dataObject.SetData("ItemDragEventArgs", new ItemDragEventArgs(selectionCollection));
            MS.DragEventArgs dragOverEventArgs = new MS.DragEventArgs(dataObject);

            // Get the DragDropTarget element that is under the pointer, if any:
            TItemContainerType targetItemContainer;
            DragDropTarget <TItemsControlType, TItemContainerType> dragDropTargetUnderPointer = GetDragDropTargetUnderPointer(_pointerX, _pointerY, out targetItemContainer);

            // Check if the element under the pointer has changed since the last PointerMoved:
            if (_previousdragDropTargetUnderPointer != dragDropTargetUnderPointer)
            {
                //---------------------------------
                // IF WHAT IS UNDER THE POINTER HAS CHANGED
                //---------------------------------

                // Raise the DragLeave event of the element that was under the pointer before:
                if (_previousdragDropTargetUnderPointer != null && _previousdragDropTargetUnderPointer.DragLeave != null)
                {
                    _previousdragDropTargetUnderPointer.DragLeave(_previousdragDropTargetUnderPointer, new MS.DragEventArgs(dataObject));

                    // Reset the value of "_isDragCancelled" when leaving a control. This variable lets the user prevent a Drop on an element when the user sets e.Handled=true in the "DragOver" event of that element.
                    _isDragCancelled = false;
                }
                // Remember the element that is under the pointer:
                _previousdragDropTargetUnderPointer = dragDropTargetUnderPointer;

                // Raise the DragEnter event of the new element that is under the pointer:
                if (dragDropTargetUnderPointer != null && dragDropTargetUnderPointer.DragEnter != null)
                {
                    dragDropTargetUnderPointer.DragEnter(dragDropTargetUnderPointer, new MS.DragEventArgs(dataObject));
                }
            }

            if (dragDropTargetUnderPointer != null)
            {
                //---------------------------------
                // IF UNDER THE POINTER THERE IS A DRAGDROPPANEL
                //---------------------------------

                // Raise the DragOver:
                dragDropTargetUnderPointer.OnDragOver(dragOverEventArgs);

                // Cancel the drag drop operation if the user has marked the DragOver event as "handled":
                if (dragOverEventArgs.Handled && dragOverEventArgs.Effects == DragDropEffects.None)
                {
                    _isDragCancelled = true;
                }
            }

            // Show the appropriate icon depending on whether it is possible to drop or not:
            if (dragDropTargetUnderPointer != null && dragDropTargetUnderPointer.AllowDrop && !_isDragCancelled)
            {
                //---------------------------------
                // SHOW ICON "DRAG ALLOWED"
                //---------------------------------
                _iconArrow.Visibility = Visibility.Visible;
                _iconStop.Visibility  = Visibility.Collapsed;
            }
            else
            {
                //---------------------------------
                // SHOW ICON "DRAG FORBIDDEN"
                //---------------------------------
                _iconArrow.Visibility = Visibility.Collapsed;
                _iconStop.Visibility  = Visibility.Visible;
            }
#endif
        }
        /// <summary>
        /// Adds all selected items when drag operation begins.
        /// </summary>
        /// <param name="eventArgs">Information about the event.</param>
        protected override void OnItemDragStarting(ItemDragEventArgs eventArgs)
        {
            SelectionCollection selectionCollection = new SelectionCollection();

            // If panel is virtualized there is no way of knowing the precise
            // index of each selected item.
            Panel itemsHost = this.ListBox.GetItemsHost();

            if (itemsHost is VirtualizingPanel)
            {
                foreach (object item in this.ListBox.SelectedItems)
                {
                    selectionCollection.Add(new Selection(item));
                }

                // Adding the item dragged even if it isn't selected
                SelectionCollection defaultSelectionCollection = SelectionCollection.ToSelectionCollection(eventArgs.Data);

                if (defaultSelectionCollection.Count == 1 && !selectionCollection.Any(selection => object.Equals(selection.Item, defaultSelectionCollection[0].Item)))
                {
                    selectionCollection.Add(defaultSelectionCollection[0]);
                }
            }
            else
            {
                for (int cnt = 0; cnt < this.ListBox.Items.Count; cnt++)
                {
                    ListBoxItem listBoxItem = this.ListBox.ItemContainerGenerator.ContainerFromIndex(cnt) as ListBoxItem;
                    if (listBoxItem.IsSelected)
                    {
                        selectionCollection.Add(new Selection(cnt, this.ListBox.Items[cnt]));
                    }
                }

                // Adding the item dragged even if it isn't selected
                SelectionCollection defaultSelectionCollection = GetSelectionCollection(eventArgs.Data);
                if (defaultSelectionCollection.Count == 1)
                {
                    if (selectionCollection.All(selection => selection.Index != defaultSelectionCollection[0].Index))
                    {
                        selectionCollection.Add(defaultSelectionCollection[0]);
                    }
                }
            }

            eventArgs.Data = selectionCollection;

            CardPanel cardPanel = new CardPanel();
            IEnumerable <UIElement> itemContainers =
                selectionCollection.SelectedItems
                .Select(item => this.ListBox.ItemContainerGenerator.ContainerFromItem(item))
                .Where(item => item != null)
                .OfType <UIElement>();

            foreach (ListBoxItem row in itemContainers)
            {
                cardPanel.Children.Add(new Image {
                    Source = new WriteableBitmap(row, new TranslateTransform())
                });
            }

            eventArgs.DragDecoratorContent = cardPanel;

            eventArgs.Handled = true;
            base.OnItemDragStarting(eventArgs);
        }