schangxiang@126.com
2025-11-04 ca398287db3f5ea01f03aac4a85edb13b28100a6
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
92
93
94
95
96
97
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
 
namespace XHandler.Class
{
    public static class Win32
    {
        public struct POINT { public Int32 X; public Int32 Y; }
 
        // During drag-and-drop operations, the position of the mouse cannot be
        // reliably determined through GetPosition. This is because control of
        // the mouse (possibly including capture) is held by the originating
        // element of the drag until the drop is completed, with much of the
        // behavior controlled by underlying Win32 calls. As a workaround, you
        // might need to use Win32 externals such as GetCursorPos.
 
        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(ref POINT point);
 
    }
 
    public class DragDropAdorner : Adorner
    {
        List<FrameworkElement> mDraggedElementList = null;
        FrameworkElement mDraggedElement = null;
        public DragDropAdorner(UIElement parent,List<UIElement> parentList=null) : base(parent)
        {
            IsHitTestVisible = false; // Seems Adorner is hit test visible?
            if (parentList == null)
            {
                mDraggedElement = parent as FrameworkElement;
            }
            else
            {
                mDraggedElementList = new List<FrameworkElement>();
                foreach (UIElement u in parentList)
                {
                    mDraggedElementList.Add(u as FrameworkElement);
                }
            }
        }
 
        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            if (mDraggedElementList != null)
            {
                Win32.POINT screenPos = new Win32.POINT();
                if (Win32.GetCursorPos(ref screenPos))
                {
                    double xValue = 0.0d;
                    double yValue = 0.0d;
                    foreach (FrameworkElement u in mDraggedElementList)
                    {
                        xValue += u.ActualWidth;
                        yValue += u.ActualHeight;
                        Point pos = PointFromScreen(new Point(screenPos.X, screenPos.Y));
                        Rect rect = new Rect(pos.X, pos.Y+yValue, u.ActualWidth, u.ActualHeight);
                        drawingContext.PushOpacity(0.5);
                        Brush highlight = u.TryFindResource(SystemColors.HighlightBrushKey) as Brush;
                        //if (highlight != null)
                        //    drawingContext.DrawRectangle(highlight, new Pen(Brushes.Transparent, 0), rect);
                        drawingContext.DrawRectangle(new VisualBrush(u), new Pen(Brushes.Transparent, 0), rect);
                    }
 
                    drawingContext.Pop();
                }
            }
            else if(mDraggedElementList == null) 
            {
                if (mDraggedElement != null)
                {
                    Win32.POINT screenPos = new Win32.POINT();
                    if (Win32.GetCursorPos(ref screenPos))
                    {
                        Point pos = PointFromScreen(new Point(screenPos.X, screenPos.Y));
                        Rect rect = new Rect(pos.X, pos.Y, mDraggedElement.ActualWidth, mDraggedElement.ActualHeight);
                        drawingContext.PushOpacity(0.5);
                        Brush highlight = mDraggedElement.TryFindResource(SystemColors.HighlightBrushKey) as Brush;
                        //if (highlight != null)
                        //    drawingContext.DrawRectangle(highlight, new Pen(Brushes.Transparent, 0), rect);
                        drawingContext.DrawRectangle(new VisualBrush(mDraggedElement), new Pen(Brushes.Transparent, 0), rect);
                        drawingContext.Pop();
                    }
                }
            }
        }
 
    }
}