From 83fbda7f6d1b2120d18485e63870b6b42f72d748 Mon Sep 17 00:00:00 2001 From: zengwenjie <1663900244@qq.com> Date: Thu, 18 Sep 2025 18:03:00 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99=E6=8B=96=E6=94=BE=E8=A3=85?= =?UTF-8?q?=E9=A5=B0=E5=99=A8=E7=9A=84=E8=BE=85=E5=8A=A9=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DeedyDesigner/Deedy.Activity/ActionViewer.cs | 11 +-- .../Adorner/DragPlacementAdorner.cs | 71 +++++++++++++++++++ DeedyDesigner/Deedy.Activity/Helper.cs | 49 +++++++++++++ 3 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs diff --git a/DeedyDesigner/Deedy.Activity/ActionViewer.cs b/DeedyDesigner/Deedy.Activity/ActionViewer.cs index 14e9501..d2c8f53 100644 --- a/DeedyDesigner/Deedy.Activity/ActionViewer.cs +++ b/DeedyDesigner/Deedy.Activity/ActionViewer.cs @@ -729,14 +729,7 @@ namespace Deedy.Activity if (eventSource is not ActionViewer && eventSource is DependencyObject dobj && this == dobj.FindAncestor()) result = true; return result; } - protected virtual void RemoveDragAdorner() - { - //TODO:移除拖拽装饰器 - } - protected virtual void UpdateDragAdorner(Dock? dock) - { - //TODO:更新拖拽装饰器 - } + #region 订阅的交互事件 protected override void OnDragEnter(DragEventArgs e) { @@ -904,7 +897,7 @@ namespace Deedy.Activity /// 节点被选中 /// /// - /// 节点被选中:当视图节点被选中时发生 + /// 当视图节点被选中时发生 /// public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble, typeof(EventHandler), typeof(ActionViewer)); diff --git a/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs b/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs new file mode 100644 index 0000000..f7e9452 --- /dev/null +++ b/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Media; + +namespace Deedy.Activity +{ + public class DragPlacementAdorner : Adorner + { + private static readonly Pen _PrevPen; + private static readonly Pen _NextPen; + private static readonly Pen _PartPen; + public Dock? Position { get; private set; } + + static DragPlacementAdorner() + { + // 定义装饰器的画笔 + _PrevPen = new Pen(Brushes.Red, 5.0); + _PrevPen.Freeze(); + _NextPen = new Pen(Brushes.Red, 5.0); + _NextPen.Freeze(); + _PartPen = new Pen(Brushes.Blue, 3.0); + _PartPen.Freeze(); + } + + public DragPlacementAdorner(UIElement adornedElement, Dock? dock) : base(adornedElement) + { + this.Position = dock; + IsHitTestVisible = false; + } + + protected override void OnRender(DrawingContext drawingContext) + { + var adornedElementRect = new Rect(AdornedElement.RenderSize); + + // 根据位置信息绘制不同的视觉效果 + switch (this.Position) + { + case Dock.Top: + drawingContext.DrawLine(_PrevPen, + new Point(0, 0), + new Point(adornedElementRect.Right, 0)); + break; + case Dock.Bottom: + drawingContext.DrawLine(_NextPen, + new Point(0, adornedElementRect.Bottom), + new Point(adornedElementRect.Right, adornedElementRect.Bottom)); + break; + case Dock.Left: + drawingContext.DrawLine(_PrevPen, + new Point(0, 0), + new Point(0, adornedElementRect.Bottom)); + break; + case Dock.Right: + drawingContext.DrawLine(_NextPen, + new Point(adornedElementRect.Right, 0), + new Point(adornedElementRect.Right, adornedElementRect.Bottom)); + break; + case null: + drawingContext.DrawRectangle(null, _PartPen, adornedElementRect); + break; + default: break; + } + } + } +} diff --git a/DeedyDesigner/Deedy.Activity/Helper.cs b/DeedyDesigner/Deedy.Activity/Helper.cs index b74f37e..a0ac12a 100644 --- a/DeedyDesigner/Deedy.Activity/Helper.cs +++ b/DeedyDesigner/Deedy.Activity/Helper.cs @@ -7,6 +7,9 @@ using System.Threading.Tasks; using System.Windows.Media; using System.Windows; using System.Runtime.CompilerServices; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Collections.Concurrent; namespace Deedy.Activity { @@ -299,5 +302,51 @@ namespace Deedy.Activity } [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_ParentElement")] private static extern void ActionSetter_ParentElement(BasalAction action, IElement? value); + /// + /// 拖放装饰层的集合 + /// + private readonly static ConcurrentDictionary AdornerLayers = new(); + /// + /// 拖放装饰器的集合 + /// + private readonly static ConcurrentDictionary DragAdorners = new(); + /// + /// 移除一个「UIElement」上的拖放装饰器 + /// + /// 目标「UIElement」对象 + public static void RemoveDragAdorner(this UIElement viewer) + { + if (viewer is null) return; + AdornerLayers.Remove(viewer, out var _AdornerLayer); + DragAdorners.Remove(viewer, out var _DragAdorner); + + if (_AdornerLayer != null && _DragAdorner != null) + _AdornerLayer.Remove(_DragAdorner); + + if (_AdornerLayer != null) _AdornerLayer = null; + if (_DragAdorner != null) _DragAdorner = null; + } + /// + /// 更新一个「UIElement」上的拖放装饰器 + /// + /// 目标「UIElement」对象 + /// 画线位置,「null」表示画4面框线 + public static void UpdateDragAdorner(this UIElement viewer, Dock? dock) + { + if (viewer is null) return; + AdornerLayers.Remove(viewer, out var _AdornerLayer); + DragAdorners.Remove(viewer, out var _DragAdorner); + + if (_AdornerLayer != null && _DragAdorner != null) + _AdornerLayer.Remove(_DragAdorner); + + _AdornerLayer ??= AdornerLayer.GetAdornerLayer(viewer); + if (_AdornerLayer is null) return; + _DragAdorner = new DragPlacementAdorner(viewer, dock); + _AdornerLayer.Add(_DragAdorner); + + AdornerLayers.TryAdd(viewer, _AdornerLayer); + DragAdorners.TryAdd(viewer, _DragAdorner); + } } }