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); + } } }