using GongSolutions.Wpf.DragDrop; using GongSolutions.Wpf.DragDrop.Utilities; using System.Collections.Generic; using System.ComponentModel; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Markup; using System.Linq; using System.Collections; using WPFProject.Models; namespace WPFProject.Utils { public class DdDropHandler : DefaultDropHandler { public bool CanConvert(IDropInfo dropInfo) { bool InterfaceFilter(Type t, object o) => (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)); Type[] enumerableInterfaces = dropInfo.TargetCollection.GetType().FindInterfaces(InterfaceFilter, null); var enumerableTypes = from i in enumerableInterfaces select i.GetGenericArguments().Single(); if (enumerableTypes.Any()) { Type dataType = TypeUtilities.GetCommonBaseClass(ExtractData(dropInfo.Data)); return dataType == typeof(FuncModel) && enumerableTypes.Any(t => t==typeof(Step)); } return false; } public Step ConvertFunc2Step(FuncModel func) { return new Step { Name = func.Name }; } public override void DragOver(IDropInfo dropInfo) { if (CanAcceptData(dropInfo)) { base.DragOver(dropInfo); } else if (CanConvert(dropInfo)) { // 固定Copy dropInfo.Effects = DragDropEffects.Copy; var isTreeViewItem = dropInfo.InsertPosition.HasFlag(RelativeInsertPosition.TargetItemCenter) && dropInfo.VisualTargetItem is TreeViewItem; dropInfo.DropTargetAdorner = isTreeViewItem ? DropTargetAdorners.Highlight : DropTargetAdorners.Insert; } } public override void Drop(IDropInfo dropInfo) { if (CanAcceptData(dropInfo)) { base.Drop(dropInfo); } else if (CanConvert(dropInfo)) { int insertIndex = GetInsertIndex(dropInfo); var destinationList = dropInfo.TargetCollection.TryGetList(); var data = ExtractData(dropInfo.Data).OfType().ToList(); if (destinationList != null) { var objects2Insert = new List(); foreach (var o in data) { var obj2Insert = ConvertFunc2Step(o as FuncModel); objects2Insert.Add(obj2Insert); destinationList.Insert(insertIndex++, obj2Insert); // 下方对象如果实现了 IDragItemSource 接口,会在这里调用 ItemDropped 方法,算是后置处理 if (obj2Insert is IDragItemSource dragItemSource) { dragItemSource.ItemDropped(dropInfo); } } SelectDroppedItems(dropInfo, objects2Insert); } } } } }