/// <summary> /// Occurs when activity of the current drag drop operation has changed. /// </summary> /// <param name="sender">The event source.</param> /// <param name="e">The event data.</param> protected virtual void OnDragActivityChanged(object?sender, EventArgs e) { Contract.RequireNotNull(sender, out IDragSourceControl Ctrl); bool IsHandled = false; switch (Ctrl.DragActivity) { case DragActivity.Idle: IsHandled = true; break; case DragActivity.Starting: bool IsDragPossible = DragSource.IsDragPossible(out _, out IList ItemList); Debug.Assert(IsDragPossible); SetDragItemList(DragSource, ItemList); CancellationToken cancellation = new CancellationToken(); NotifyDragStarting(cancellation); if (cancellation.IsCanceled) { Ctrl.CancelDrag(); } IsHandled = true; break; case DragActivity.Started: DataObject Data = new DataObject(DragSource.GetType(), DragSource); DragDropEffects AllowedEffects = DragDropEffects.Move; if (DragSource.AllowDropCopy) { AllowedEffects |= DragDropEffects.Copy; } DragDrop.DoDragDrop(this, Data, AllowedEffects); ClearCurrentDropTarget(); IsHandled = true; break; default: break; } Debug.Assert(IsHandled); }
/// <summary> /// Gets the drag source from arguments of a drag drop event. /// </summary> /// <param name="e">The event data.</param> /// <param name="dragSource">The drag source upon return.</param> /// <returns>True if successful.</returns> protected virtual bool GetValidDragSourceFromArgs(DragEventArgs e, out IDragSourceControl dragSource) { if (e.Data.GetDataPresent(DragSource.GetType())) { if (e.Data.GetData(DragSource.GetType()) is IDragSourceControl AsDragSource) { if (AsDragSource.HasDragItemList(out object RootItem, out IList _) && IsSameTypeAsContent(RootItem)) { dragSource = AsDragSource; return(true); } } } Contract.Unused(out dragSource); return(false); }
/// <summary> /// Invoked when an unhandled <see cref="UIElement.Drop"/> attached event reaches an element in its route that is derived from this class. /// </summary> /// <param name="e">The event data.</param> protected override void OnDrop(DragEventArgs e) { e.Effects = GetAllowedDropEffects(e); e.Handled = true; if (e.Effects != DragDropEffects.None) { ExtendedTreeViewItemBase?ItemContainer = GetEventSourceItem(e); IDragSourceControl AsDragSource = (IDragSourceControl)e.Data.GetData(DragSource.GetType()); bool IsDragPossible = AsDragSource.IsDragPossible(out object SourceItem, out IList ItemList); object?DestinationItem = ItemContainer != null ? ItemContainer.Content : null; UnselectAll(); if (IsDragPossible && DestinationItem != null) { IList CloneList = CreateItemList(); Debug.Assert(CloneList.Count == 0); NotifyPreviewDropCompleted(DestinationItem, e.Effects, ItemList, CloneList); if (e.Effects == DragDropEffects.Copy) { DragDropCopy(SourceItem, DestinationItem, ItemList, CloneList); } else if (e.Effects == DragDropEffects.Move) { DragDropMove(SourceItem, DestinationItem, ItemList); } Debug.Assert(CloneList.Count > 0 || e.Effects != DragDropEffects.Copy); NotifyDropCompleted(DestinationItem, e.Effects, ItemList, CloneList); Expand(DestinationItem); } } }