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)); } }
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; } } } }
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); }