alielie
2025-07-04 0940f31b7eba1cf6b6a8c1fca72d97cf686e79f2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using GongSolutions.Wpf.DragDrop;
using GongSolutions.Wpf.DragDrop.Utilities;
using Plugin.TestBuilder.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
 
namespace Plugin.TestBuilder.UI
{
    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<object>().ToList();
 
                if (destinationList != null)
                {
                    var objects2Insert = new List<object>();
 
                    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);
                }
            }
            
        }
 
    }
}