From ba725b7bfe324033d46bc0f89d711c557580b5d2 Mon Sep 17 00:00:00 2001 From: zengwenjie <1663900244@qq.com> Date: Fri, 26 Sep 2025 14:40:02 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=A7=84=E5=88=92=E6=8B=96?= =?UTF-8?q?=E6=94=BE=E8=A3=85=E9=A5=B0=E5=99=A8=E7=BB=98=E5=88=B6=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DeedyDesigner/Deedy.Activity/ActionViewer.cs | 7 ++- .../Adorner/DragPlacementAdorner.cs | 59 +++++-------------- .../Contract/Interface/ICombinedElement.cs | 1 + .../DeedyAction/FlowAction/CombinedLogical.cs | 1 + .../FlowAction/ContainerLogical.cs | 1 + .../FuncAction/CombinedFunction.cs | 1 + .../FuncAction/ContainerFunction.cs | 1 + .../DeedyVisual/IVisualLayout.cs | 1 - .../DeedyVisual/VisualLayout.cs | 2 + .../Deedy.Activity/Helpers/ViewerHelper.cs | 7 ++- .../Deedy.Activity/Helpers/VisualHelper.cs | 41 ++++++------- 11 files changed, 50 insertions(+), 72 deletions(-) diff --git a/DeedyDesigner/Deedy.Activity/ActionViewer.cs b/DeedyDesigner/Deedy.Activity/ActionViewer.cs index 0317cc0..d964b26 100644 --- a/DeedyDesigner/Deedy.Activity/ActionViewer.cs +++ b/DeedyDesigner/Deedy.Activity/ActionViewer.cs @@ -748,6 +748,7 @@ namespace Deedy.Activity protected internal DropPlacement _DropPlacement = DropPlacement.Uncertain; protected override void OnDragOver(DragEventArgs e) { + //HACK:这里要考虑父容器的布局方向 if (this.IsEventNeedToHandle(e.OriginalSource)) { this.RefreshViewerState(true); @@ -759,17 +760,17 @@ namespace Deedy.Activity if (this._CanDropInParent && (currentPoint.Y < 10 || currentPoint.Y < 10)) { this._DropPlacement = DropPlacement.BeforeMe; - this.UpdateDragAdorner(Dock.Top); + this.UpdateDragAdorner(this._DropPlacement); } else if (this._CanDropInParent && (hitElement.ActualHeight - currentPoint.Y < 10 || hitElement.ActualWidth - currentPoint.X < 10)) { this._DropPlacement = DropPlacement.BehindMe; - this.UpdateDragAdorner(Dock.Bottom); + this.UpdateDragAdorner(this._DropPlacement); } else if (this._CanDropChild) { this._DropPlacement = DropPlacement.WithinMe; - this.UpdateDragAdorner(null); + this.UpdateDragAdorner(this._DropPlacement); } else { diff --git a/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs b/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs index f7e9452..0b2ff36 100644 --- a/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs +++ b/DeedyDesigner/Deedy.Activity/Adorner/DragPlacementAdorner.cs @@ -7,65 +7,34 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; +using Deedy.Activity.Helpers; 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; } + private static readonly Pen _Pen; + private static readonly Brush _Brush; + public DropPlacement DropPlacement { get; private set; } + public LayoutDirection? LayoutDirection { 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(); + // 定义装饰器的画笔与画刷 + _Pen = new Pen(Brushes.Transparent, 0); + _Pen.Freeze(); + _Brush = new SolidColorBrush(Colors.Red) { Opacity = 0.5 }; + _Brush.Freeze(); } - public DragPlacementAdorner(UIElement adornedElement, Dock? dock) : base(adornedElement) + public DragPlacementAdorner(UIElement adornedElement, DropPlacement dropPlacement, LayoutDirection? parentLayoutDirection) : base(adornedElement) { - this.Position = dock; + this.DropPlacement = dropPlacement; + this.LayoutDirection = parentLayoutDirection; 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; - } - } + => this.Help_DrawDropAdorner(drawingContext, this.DropPlacement, this.LayoutDirection, _Pen, _Brush); } } diff --git a/DeedyDesigner/Deedy.Activity/Contract/Interface/ICombinedElement.cs b/DeedyDesigner/Deedy.Activity/Contract/Interface/ICombinedElement.cs index e46843d..14e7e81 100644 --- a/DeedyDesigner/Deedy.Activity/Contract/Interface/ICombinedElement.cs +++ b/DeedyDesigner/Deedy.Activity/Contract/Interface/ICombinedElement.cs @@ -13,5 +13,6 @@ namespace Deedy.Activity public interface ICombinedElement : IElement { public ElementCollection Elements { get; set; } + public LayoutDirection Direction { get; set; } } } diff --git a/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/CombinedLogical.cs b/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/CombinedLogical.cs index 3d33075..73b9f06 100644 --- a/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/CombinedLogical.cs +++ b/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/CombinedLogical.cs @@ -11,5 +11,6 @@ namespace Deedy.Activity public CombinedLogical() { } public ElementCollection Elements { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public LayoutDirection Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } } diff --git a/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs b/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs index fe0bc18..6d4fbc6 100644 --- a/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs +++ b/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs @@ -12,6 +12,7 @@ namespace Deedy.Activity public ContainerLogical() { } public abstract ElementCollection Elements { get; set; } + public LayoutDirection Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public abstract void Append(IElement element); public abstract bool CombineChecking(IElement element, out DragDropEffects effects); diff --git a/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/CombinedFunction.cs b/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/CombinedFunction.cs index 0134ba0..0f2656d 100644 --- a/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/CombinedFunction.cs +++ b/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/CombinedFunction.cs @@ -11,5 +11,6 @@ namespace Deedy.Activity public CombinedFunction() { } public ElementCollection Elements { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public LayoutDirection Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } } diff --git a/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs b/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs index 941df5e..dad4b0f 100644 --- a/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs +++ b/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs @@ -12,6 +12,7 @@ namespace Deedy.Activity public ContainerFunction() { } public abstract ElementCollection Elements { get; set; } + public LayoutDirection Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public abstract void Append(IElement element); public abstract bool CombineChecking(IElement element, out DragDropEffects effects); diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs index cb84d8b..d35ce79 100644 --- a/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs +++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs @@ -8,6 +8,5 @@ namespace Deedy.Activity { public interface IVisualLayout : IContainerElement { - LayoutDirection LayoutDirection { get; } } } diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs index 4c52ff8..9aa0dce 100644 --- a/DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs +++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs @@ -36,6 +36,8 @@ namespace Deedy.Activity public LayoutDirection LayoutDirection => throw new NotImplementedException(); + public LayoutDirection Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public event PropertyChangedEventHandler? PropertyChanged; /// diff --git a/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs index 2c43098..2af7360 100644 --- a/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs +++ b/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs @@ -40,8 +40,9 @@ namespace Deedy.Activity /// 更新一个「UIElement」上的拖放装饰器 /// /// 目标「UIElement」对象 - /// 画线位置,「null」表示画4面框线 - public static void UpdateDragAdorner(this UIElement viewer, Dock? dock) + /// 放置位置或放置模式 + /// 父容器布局方向 + public static void UpdateDragAdorner(this UIElement viewer, DropPlacement dropPlacement, LayoutDirection? parentLayoutDirection = null) { if (viewer is null) return; AdornerLayers.Remove(viewer, out var _AdornerLayer); @@ -52,7 +53,7 @@ namespace Deedy.Activity _AdornerLayer ??= AdornerLayer.GetAdornerLayer(viewer); if (_AdornerLayer is null) return; - _DragAdorner = new DragPlacementAdorner(viewer, dock); + _DragAdorner = new DragPlacementAdorner(viewer, dropPlacement, parentLayoutDirection); _AdornerLayer.Add(_DragAdorner); AdornerLayers.TryAdd(viewer, _AdornerLayer); diff --git a/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs index 3c52f40..c535a3e 100644 --- a/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs +++ b/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs @@ -8,6 +8,7 @@ using System.Windows; using System.ComponentModel; using System.Windows.Controls; using Drawing = System.Drawing; +using System.Windows.Documents; namespace Deedy.Activity.Helpers { @@ -22,13 +23,14 @@ namespace Deedy.Activity.Helpers /// 要绘制的「UIElement」元素 /// 「UIElement」元素的绘图上下文 /// 拖放操作的放置位置 - /// 父级布局的布局方向 - public static void Help_DrawDropAdorner(this UIElement ui, DrawingContext dc, DropPlacement dropPlacement, LayoutDirection parentLayout) + /// 父级布局的布局方向 + public static void Help_DrawDropAdorner(this UIElement ui, DrawingContext dc, + DropPlacement dropPlacement, LayoutDirection? parentLayoutDirection, + Pen? _Pen = null, Brush? _Brush = null) { if (ui == null || dc == null || dropPlacement == DropPlacement.UnDragged) return; - Pen pen = new Pen(Brushes.Transparent, 0); - pen.Freeze(); - Brush brush = new SolidColorBrush(Colors.Red) { Opacity = 0.5 }; + Pen pen = _Pen ?? new Pen(Brushes.Transparent, 0); + Brush brush = _Brush ?? new SolidColorBrush(Colors.Red) { Opacity = 0.5 }; Size size = ui.RenderSize; ThemeResources res = new(); @@ -42,21 +44,21 @@ namespace Deedy.Activity.Helpers break; case DropPlacement.BeforeMe: { - if (parentLayout == LayoutDirection.Horizontal) + if (parentLayoutDirection == LayoutDirection.Horizontal) dc.DrawRectangle(brush, pen, new(0, 0, 4, size.Height)); - else if (parentLayout == LayoutDirection.Vertical) + else if (parentLayoutDirection == LayoutDirection.Vertical) dc.DrawRectangle(brush, pen, new(0, 0, size.Width, 4)); - else if (parentLayout == LayoutDirection.Stacked) + else if (parentLayoutDirection == LayoutDirection.Stacked) dc.DrawGeometry(brush, pen, res.DropIcon_BringForward); } break; case DropPlacement.BehindMe: { - if (parentLayout == LayoutDirection.Horizontal) + if (parentLayoutDirection == LayoutDirection.Horizontal) dc.DrawRectangle(brush, pen, new(size.Width - 4, 0, 4, size.Height)); - else if (parentLayout == LayoutDirection.Vertical) + else if (parentLayoutDirection == LayoutDirection.Vertical) dc.DrawRectangle(brush, pen, new(size.Height - 4, 0, size.Width, 4)); - else if (parentLayout == LayoutDirection.Stacked) + else if (parentLayoutDirection == LayoutDirection.Stacked) dc.DrawGeometry(brush, pen, res.DropIcon_SendBackward); } break; @@ -72,7 +74,7 @@ namespace Deedy.Activity.Helpers /// /// 检查拖放操作的模式 /// - /// 要检查的「UIElement」元素 + /// 要检查的「UIElement」元素 /// 检查点位置 /// 检查后的拖放位置;其中不包括「DropPlacement.UnDragged」与「DropPlacement.Uncertain」 /// @@ -80,22 +82,21 @@ namespace Deedy.Activity.Helpers /// 「DropPlacement.Uncertain」= 拖放内容不是可视化元素 /// ··以上两种情况需要在调用此方法前进行判定 /// - public static DropPlacement Help_CheckDropPlacement(this UIElement ui, Point point) + public static DropPlacement Help_CheckDropPlacement(this IElement element, Size size, Point point) { DropPlacement result = DropPlacement.UnDragged; - if (ui != null) + if (element != null) { - Size size = ui.RenderSize; double horRuler = size.Width / 3; if (horRuler > 20) horRuler = 20; double verRuler = size.Height / 3; if (verRuler > 20) verRuler = 20; LayoutDirection direction = LayoutDirection.Cannot; - if (ui is IVisualLayout layout) + if (element is ICombinedElement) { - if (ui is FrameworkElement fe && fe.Parent is IVisualLayout parentLayout) + if (element.ParentElement is ICombinedElement parentLayout) { - direction = parentLayout.LayoutDirection; + direction = parentLayout.Direction; if (direction == LayoutDirection.Decorator) { if (point.X < horRuler @@ -120,9 +121,9 @@ namespace Deedy.Activity.Helpers } else { - if (ui is FrameworkElement fe && fe.Parent is IVisualLayout parentLayout) + if (element.ParentElement is ICombinedElement parentLayout) { - direction = parentLayout.LayoutDirection; + direction = parentLayout.Direction; if (direction == LayoutDirection.Decorator) result = DropPlacement.ReplaceMe; else if (direction == LayoutDirection.Cannot)