From 7a68bca5b7f4eb8770751b8d4d9665fab5a1a83c Mon Sep 17 00:00:00 2001
From: zengwenjie <1663900244@qq.com>
Date: Thu, 18 Sep 2025 19:08:24 +0800
Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=A7=84=E5=88=92Helper?=
=?UTF-8?q?=E7=B1=BB=E7=9A=84=E5=8A=9F=E8=83=BD=E4=B8=8E=E7=BB=93=E6=9E=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
DeedyDesigner/Deedy.Activity/ActionViewer.cs | 6 +-
.../Contract/Interface/IContainerElement.cs | 10 +-
.../FlowAction/ContainerLogical.cs | 9 +-
.../FuncAction/ContainerFunction.cs | 17 +-
.../Deedy.Activity/DeedyVisual/DeedyLayout.cs | 17 ++
DeedyDesigner/Deedy.Activity/Helper.cs | 266 ------------------
.../Deedy.Activity/Helpers/ActionHelper.cs | 143 +++++++++-
.../Deedy.Activity/Helpers/ActivityHelper.cs | 13 +
.../Deedy.Activity/Helpers/ElementHelper.cs | 95 +++++++
.../Deedy.Activity/Helpers/RuntimeHelper.cs | 29 ++
.../Deedy.Activity/Helpers/ViewerHelper.cs | 62 ++++
.../Deedy.Activity/Helpers/VisualHelper.cs | 12 +
DeedyDesigner/Deedy.Activity/IElement.cs | 12 +-
13 files changed, 398 insertions(+), 293 deletions(-)
create mode 100644 DeedyDesigner/Deedy.Activity/Helpers/ActivityHelper.cs
create mode 100644 DeedyDesigner/Deedy.Activity/Helpers/ElementHelper.cs
create mode 100644 DeedyDesigner/Deedy.Activity/Helpers/RuntimeHelper.cs
create mode 100644 DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs
create mode 100644 DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
diff --git a/DeedyDesigner/Deedy.Activity/ActionViewer.cs b/DeedyDesigner/Deedy.Activity/ActionViewer.cs
index d2c8f53..801f852 100644
--- a/DeedyDesigner/Deedy.Activity/ActionViewer.cs
+++ b/DeedyDesigner/Deedy.Activity/ActionViewer.cs
@@ -618,7 +618,7 @@ namespace Deedy.Activity
if (withExitline.ExitlinePosition.HasFlag(ExitlinePosition.Rightlower))
this.ShowRightExitline = Visibility.Visible;
// 新元素被托管渲染后调整子元素退出线位置
- withExitline.AdjustExitlinePosition();
+ withExitline.Help_AdjustExitlinePosition();
}
if (newValue is ILogicController logicController)
@@ -646,7 +646,7 @@ namespace Deedy.Activity
this.ElementCount = combined.Elements.Count;
}
// 节点集合变更时调整退出线位置
- if (this.ActionElement is IContainerWithExitline container) container.AdjustExitlinePosition();
+ if (this.ActionElement is IContainerWithExitline container) container.Help_AdjustExitlinePosition();
}
protected virtual void ActionElement_PropertyChanged(object? sender, PropertyChangedEventArgs e)
@@ -662,7 +662,7 @@ namespace Deedy.Activity
break;
case nameof(IContainerWithExitline.ExitlinePosition):
// 自身退出线变更时调整所有子节点退出线位置
- (this.ActionElement as IContainerWithExitline)?.AdjustExitlinePosition();
+ (this.ActionElement as IContainerWithExitline)?.Help_AdjustExitlinePosition();
break;
default: break;
}
diff --git a/DeedyDesigner/Deedy.Activity/Contract/Interface/IContainerElement.cs b/DeedyDesigner/Deedy.Activity/Contract/Interface/IContainerElement.cs
index f469cc4..fd108e1 100644
--- a/DeedyDesigner/Deedy.Activity/Contract/Interface/IContainerElement.cs
+++ b/DeedyDesigner/Deedy.Activity/Contract/Interface/IContainerElement.cs
@@ -9,15 +9,15 @@ namespace Deedy.Activity
{
public interface IContainerElement : ICombinedElement
{
- public void Append(IElement element) => this.Elements.Add(element);
- public void Remove(IElement element) => this.Elements.Remove(element);
- public void Insert(IElement element, uint index) => this.Help_Insert(element, index);
- public void MoveTo(IElement element, uint index) => this.Help_MoveTo(element, index);
+ public void Append(IElement element);
+ public void Remove(IElement element);
+ public void Insert(IElement element, uint index);
+ public void MoveTo(IElement element, uint index);
///
/// 如果类型上没有组装规则,则认为不允许组装,否则按照组装规则处理
///
/// 要进行组装检查的单元实例
/// 是否允许组装
- public bool CombineChecking(IElement element, out DragDropEffects effects) => this.Help_CombineChecking(element, out effects);
+ public bool CombineChecking(IElement element, out DragDropEffects effects);
}
}
diff --git a/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs b/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs
index 4e43702..fe0bc18 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyAction/FlowAction/ContainerLogical.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
namespace Deedy.Activity
{
@@ -10,6 +11,12 @@ namespace Deedy.Activity
{
public ContainerLogical() { }
- public ElementCollection Elements { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public abstract ElementCollection Elements { get; set; }
+
+ public abstract void Append(IElement element);
+ public abstract bool CombineChecking(IElement element, out DragDropEffects effects);
+ public abstract void Insert(IElement element, uint index);
+ public abstract void MoveTo(IElement element, uint index);
+ public abstract void Remove(IElement element);
}
}
diff --git a/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs b/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs
index 6f3efdc..941df5e 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyAction/FuncAction/ContainerFunction.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
namespace Deedy.Activity
{
@@ -10,16 +11,12 @@ namespace Deedy.Activity
{
public ContainerFunction() { }
- public ElementCollection Elements { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public abstract ElementCollection Elements { get; set; }
- public void Append(IElement deedyElement)
- {
- throw new NotImplementedException();
- }
-
- public void Remove(IElement deedyElement)
- {
- throw new NotImplementedException();
- }
+ public abstract void Append(IElement element);
+ public abstract bool CombineChecking(IElement element, out DragDropEffects effects);
+ public abstract void Insert(IElement element, uint index);
+ public abstract void MoveTo(IElement element, uint index);
+ public abstract void Remove(IElement element);
}
}
diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs
index 2083095..9de85e5 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
namespace Deedy.Activity
{
@@ -70,6 +71,22 @@ namespace Deedy.Activity
{
throw new NotImplementedException();
}
+
+ public void Insert(IElement element, uint index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveTo(IElement element, uint index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool CombineChecking(IElement element, out DragDropEffects effects)
+ {
+ throw new NotImplementedException();
+ }
+
public void ReadyToWorking(IElement? element = null, Output? output = null)
{
throw new NotImplementedException();
diff --git a/DeedyDesigner/Deedy.Activity/Helper.cs b/DeedyDesigner/Deedy.Activity/Helper.cs
index a0ac12a..26239ea 100644
--- a/DeedyDesigner/Deedy.Activity/Helper.cs
+++ b/DeedyDesigner/Deedy.Activity/Helper.cs
@@ -82,271 +82,5 @@ namespace Deedy.Activity
return null;
}
- ///
- /// 帮助一个IElement节点构建参数映射表
- ///
- /// 需要构建参数映射表的Element节点
- /// 消息输出器
- public static void BuildParamMapping(this IElement element, Output? output = null)
- {
- //
- }
- ///
- /// 将一个元素插入到当前节点前方「前提:当前节点的父级必须是可变容器节点」
- ///
- /// 当前节点
- /// 待插入的节点
- public static void InsertElementToFore(this IElement element, IElement insertion)
- {
- if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
- }
- ///
- /// 将一个元素插入到当前节点后方「前提:当前节点的父级必须是可变容器节点」
- ///
- /// 当前节点
- /// 待插入的节点
- public static void InsertElementAtRear(this IElement element, IElement insertion)
- {
- if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
- }
- ///
- /// 将当前节点从父节点中移除
- ///
- /// 要移除的元素
- public static void RemoveFromParent(this IElement element)
- {
- if (element != null && element.ParentElement is IContainerElement container) container.Remove(element);
- }
- private static readonly Dictionary, List)> StaticField_CombineRules = [];
- ///
- /// 查询可动态组装集合的组合规则
- ///
- /// 要查询的元素
- /// 允许规则集合
- /// 禁止规则集合
- public static void GetCombineRules(this IContainerElement element,
- ref List allowTypes,
- ref List rejectTypes)
- {
- if (element == null) return;
- Type type = element.GetType();
- if (!StaticField_CombineRules.ContainsKey(type))
- {
- var _AllowTypes = new List();
- var _RejectTypes = new List();
-
- var clearRule = type.GetCustomAttribute(false);
- if (clearRule != null)
- {
- var allowRules = type.GetCustomAttributes(false);
- foreach (var rule in allowRules) _AllowTypes.Add(rule);
- var rejectRules = type.GetCustomAttributes(false);
- foreach (var rule in rejectRules) _RejectTypes.Add(rule);
- }
- else
- {
- //沿着继承链查找具备「CombineRule_ClearInheritedAttribute」特性的类型,获取组装属性
- List types = [];
- Type? baseType = type.BaseType;
- while (baseType != null)
- {
- types.Add(baseType);
- clearRule = baseType.GetCustomAttribute(false);
- if (clearRule != null) break;
- baseType = baseType.BaseType;
- }
- foreach (var ruleType in types)
- {
- var aRules = ruleType.GetCustomAttributes(false);
- foreach (var rule in aRules) _AllowTypes.Add(rule);
- var rRules = ruleType.GetCustomAttributes(false);
- foreach (var rule in rRules) _RejectTypes.Add(rule);
- }
- }
- StaticField_CombineRules.Add(type, (allowTypes, rejectTypes));
- }
-
- (List allowTypes, List rejectTypes) rules
- = StaticField_CombineRules[type];
- allowTypes.AddRange(rules.allowTypes);
- rejectTypes.AddRange(rules.rejectTypes);
- }
- ///
- /// 校验一个节点是否处于跳过执行逻辑
- ///
- /// 要检查的节点
- /// 是否需要跳过执行过程
- public static bool IsNeedBypassing(this IActionElement element)
- {
- if (element == null) return false;
- var parent = element.ParentElement;
- while (parent != null)
- {
- if (parent is IPassable passable)
- return passable.IsBypassing;
- else parent = parent.ParentElement;
- }
- return false;
- }
- ///
- /// 查找指定类型的祖辈元素
- ///
- /// 要查找的祖非类型
- /// 查找的起点
- /// 查找的层级,默认1级
- /// 如果找到根元素也未找到则返回「null」
- public static T? FindAncestorElement(this IElement element, int level = 1) where T : IElement
- {
- if (element == null || level < 1) return default;
-
- var parent = element.ParentElement;
- int currentLevel = 0;
-
- while (parent != null && currentLevel < level)
- {
- if (parent is T foundParent)
- {
- // 每次找到一个约定类型的袓辈节点计数需要加1
- currentLevel++;
- if (currentLevel >= level)
- return foundParent;
- }
- else parent = parent.ParentElement;
- }
-
- return default;
- }
- ///
- /// 调整子节点的退出线位置
- ///
- /// 要调整的带退出线容器
- public static void AdjustExitlinePosition(this IContainerWithExitline container)
- {
- if (container != null
- && (container.ExitlinePosition == ExitlinePosition.LeftLower
- || container.ExitlinePosition == ExitlinePosition.Rightlower))
- {
- var lastChild = container.Elements[container.Elements.Count - 1] as IContainerWithExitline;
- if (lastChild != null
- && (lastChild.ExitlinePosition == ExitlinePosition.LeftLower
- || lastChild.ExitlinePosition == ExitlinePosition.Rightlower))
- {
- if (container.IsExitlineAtSamePosition == true)
- {
- if (container.ExitlinePosition == ExitlinePosition.LeftLower)
- lastChild.ExitlinePosition = ExitlinePosition.LeftLower;
- if (container.ExitlinePosition == ExitlinePosition.Rightlower)
- lastChild.ExitlinePosition = ExitlinePosition.Rightlower;
- }
- if (container.IsExitlineAtSamePosition == false)
- {
- if (container.ExitlinePosition == ExitlinePosition.LeftLower)
- lastChild.ExitlinePosition = ExitlinePosition.LeftLower;
- if (container.ExitlinePosition == ExitlinePosition.Rightlower)
- lastChild.ExitlinePosition = ExitlinePosition.Rightlower;
- }
- }
- }
- }
- ///
- /// 设置「IElement」对象的「DepthLevel」属性值
- ///
- /// 要设置的对象
- /// 层级深度
- /// 如果设置失败则返回「False」
- public static bool Setter_DepthLevel(this IElement element, int depthLevel)
- {
- if (element is BasalAction action)
- {
- ActionSetter_DepthLevel(action, depthLevel);
- return true;
- }
- else
- {
- try
- {
- element.SetNamedPropertyValue(nameof(IElement.DepthLevel), depthLevel);
- return true;
- }
- catch { return false; }
- }
- }
- [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DepthLevel")]
- private static extern void ActionSetter_DepthLevel(BasalAction action, int value);
-
- ///
- /// 设置「IElement」对象的「ParentElement」属性值
- ///
- /// 要设置的对象
- /// 属性值
- /// 如果设置失败则返回「False」
- public static bool Setter_ParentElement(this IElement element, IElement? parent)
- {
- if (element is BasalAction action)
- {
- ActionSetter_ParentElement(action, parent);
- return true;
- }
- else
- {
- try
- {
- element.SetNamedPropertyValue(nameof(IElement.ParentElement), parent);
- return true;
- }
- catch
- {
- return false;
- }
- }
- }
- [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);
- }
}
}
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/ActionHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/ActionHelper.cs
index e5919c4..5c578cf 100644
--- a/DeedyDesigner/Deedy.Activity/Helpers/ActionHelper.cs
+++ b/DeedyDesigner/Deedy.Activity/Helpers/ActionHelper.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
@@ -9,17 +10,73 @@ namespace Deedy.Activity
{
public static partial class Helper
{
+ private static readonly Dictionary, List)> StaticField_CombineRules = [];
+ ///
+ /// 查询可动态组装集合的组合规则
+ ///
+ /// 要查询的元素
+ /// 允许规则集合
+ /// 禁止规则集合
+ public static void Help_GetCombineRules(this IContainerElement element,
+ ref List allowTypes,
+ ref List rejectTypes)
+ {
+ if (element == null) return;
+ Type type = element.GetType();
+ if (!StaticField_CombineRules.ContainsKey(type))
+ {
+ var _AllowTypes = new List();
+ var _RejectTypes = new List();
+
+ var clearRule = type.GetCustomAttribute(false);
+ if (clearRule != null)
+ {
+ var allowRules = type.GetCustomAttributes(false);
+ foreach (var rule in allowRules) _AllowTypes.Add(rule);
+ var rejectRules = type.GetCustomAttributes(false);
+ foreach (var rule in rejectRules) _RejectTypes.Add(rule);
+ }
+ else
+ {
+ //沿着继承链查找具备「CombineRule_ClearInheritedAttribute」特性的类型,获取组装属性
+ List types = [];
+ Type? baseType = type.BaseType;
+ while (baseType != null)
+ {
+ types.Add(baseType);
+ clearRule = baseType.GetCustomAttribute(false);
+ if (clearRule != null) break;
+ baseType = baseType.BaseType;
+ }
+ foreach (var ruleType in types)
+ {
+ var aRules = ruleType.GetCustomAttributes(false);
+ foreach (var rule in aRules) _AllowTypes.Add(rule);
+ var rRules = ruleType.GetCustomAttributes(false);
+ foreach (var rule in rRules) _RejectTypes.Add(rule);
+ }
+ }
+ StaticField_CombineRules.Add(type, (allowTypes, rejectTypes));
+ }
+
+ (List allowTypes, List rejectTypes) rules
+ = StaticField_CombineRules[type];
+ allowTypes.AddRange(rules.allowTypes);
+ rejectTypes.AddRange(rules.rejectTypes);
+ }
///
/// 如果类型上没有组装规则,则认为不允许组装,否则按照组装规则处理
///
+ /// 要校验的可动态组装容器
/// 要进行组装检查的单元实例
+ /// 校验结果
/// 是否允许组装
public static bool Help_CombineChecking(this IContainerElement container, IElement element, out DragDropEffects effects)
{
DragDropEffects resultEffects = DragDropEffects.None;
List _AllowTypes = [];
List _RejectTypes = [];
- GetCombineRules(container, ref _AllowTypes, ref _RejectTypes);
+ Help_GetCombineRules(container, ref _AllowTypes, ref _RejectTypes);
if (element == null)
{
@@ -69,19 +126,101 @@ namespace Deedy.Activity
effects = resultEffects;
return allow;
}
+ ///
+ /// 将一个元素插入到可变容器的指定位置
+ ///
+ /// 可变元素容器
+ /// 要插入的元素
+ /// 要插入的位置
public static void Help_Insert(this IContainerElement @this, IElement element, uint index)
{
if (element == null) return;
if (index < @this.Elements.Count) @this.Elements.Insert((int)index, element);
if (index >= @this.Elements.Count) @this.Elements.Add(element);
}
+ ///
+ /// 将一个元素移动到容器的指定位置
+ ///
+ /// 可变元素容器
+ /// 要移动的元素
+ /// 要移动到的位置
public static void Help_MoveTo(this IContainerElement @this, IElement element, uint index)
{
if (element == null) return;
int newIndex = (index >= @this.Elements.Count) ? @this.Elements.Count - 1 : (int)index;
int oldIndex = @this.Elements.IndexOf(element);
- if (oldIndex < 0) @this.Elements.Insert(newIndex, element);
+ if (oldIndex < 0) @this.Help_Insert(element, (uint)newIndex);
else @this.Elements.Move(oldIndex, newIndex);
}
+ ///
+ /// 帮助一个IElement节点构建参数映射表
+ ///
+ /// 需要构建参数映射表的Element节点
+ /// 消息输出器
+ public static void Help_BuildParamMapping(this IElement element, Output? output = null)
+ {
+ //TODO:构建元素的参数映射表
+ }
+ ///
+ /// 将一个元素插入到当前节点前方「前提:当前节点的父级必须是可变容器节点」
+ ///
+ /// 当前节点
+ /// 待插入的节点
+ public static void Help_InsertElementToFore(this IElement element, IElement insertion)
+ {
+ if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
+ //TODO:在当前节点前方插入新节点
+ }
+ ///
+ /// 将一个元素插入到当前节点后方「前提:当前节点的父级必须是可变容器节点」
+ ///
+ /// 当前节点
+ /// 待插入的节点
+ public static void Help_InsertElementAtRear(this IElement element, IElement insertion)
+ {
+ if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
+ //TODO:在当前节点的后方插入新节点
+ }
+ ///
+ /// 将当前节点从父节点中移除
+ ///
+ /// 要移除的元素
+ public static void Help_RemoveFromParent(this IElement element)
+ {
+ if (element != null && element.ParentElement is IContainerElement container) container.Remove(element);
+ //TODO:将当前节点从自身的父级节点中移除
+ }
+ ///
+ /// 调整子节点的退出线位置
+ ///
+ /// 要调整的带退出线容器
+ public static void Help_AdjustExitlinePosition(this IContainerWithExitline container)
+ {
+ if (container != null
+ && (container.ExitlinePosition == ExitlinePosition.LeftLower
+ || container.ExitlinePosition == ExitlinePosition.Rightlower))
+ {
+ var lastChild = container.Elements[container.Elements.Count - 1] as IContainerWithExitline;
+ if (lastChild != null
+ && (lastChild.ExitlinePosition == ExitlinePosition.LeftLower
+ || lastChild.ExitlinePosition == ExitlinePosition.Rightlower))
+ {
+ if (container.IsExitlineAtSamePosition == true)
+ {
+ if (container.ExitlinePosition == ExitlinePosition.LeftLower)
+ lastChild.ExitlinePosition = ExitlinePosition.LeftLower;
+ if (container.ExitlinePosition == ExitlinePosition.Rightlower)
+ lastChild.ExitlinePosition = ExitlinePosition.Rightlower;
+ }
+ if (container.IsExitlineAtSamePosition == false)
+ {
+ if (container.ExitlinePosition == ExitlinePosition.LeftLower)
+ lastChild.ExitlinePosition = ExitlinePosition.LeftLower;
+ if (container.ExitlinePosition == ExitlinePosition.Rightlower)
+ lastChild.ExitlinePosition = ExitlinePosition.Rightlower;
+ }
+ }
+ }
+ }
}
}
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/ActivityHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/ActivityHelper.cs
new file mode 100644
index 0000000..8a71ba9
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/Helpers/ActivityHelper.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Deedy.Activity
+{
+ public static partial class Helper
+ {
+ //TODO:管理附加属性与准备方法
+ }
+}
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/ElementHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/ElementHelper.cs
new file mode 100644
index 0000000..74b0ff1
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/Helpers/ElementHelper.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Deedy.Activity
+{
+ public static partial class Helper
+ {
+ ///
+ /// 查找指定类型的祖辈元素
+ ///
+ /// 要查找的祖非类型
+ /// 查找的起点
+ /// 查找的层级,默认1级
+ /// 如果找到根元素也未找到则返回「null」
+ public static T? FindAncestorElement(this IElement element, int level = 1) where T : IElement
+ {
+ if (element == null || level < 1) return default;
+
+ var parent = element.ParentElement;
+ int currentLevel = 0;
+
+ while (parent != null && currentLevel < level)
+ {
+ if (parent is T foundParent)
+ {
+ // 每次找到一个约定类型的袓辈节点计数需要加1
+ currentLevel++;
+ if (currentLevel >= level)
+ return foundParent;
+ }
+ else parent = parent.ParentElement;
+ }
+
+ return default;
+ }
+ ///
+ /// 设置「IElement」对象的「DepthLevel」属性值
+ ///
+ /// 要设置的对象
+ /// 层级深度
+ /// 如果设置失败则返回「False」
+ public static bool Help_Setter_DepthLevel(this IElement element, int depthLevel)
+ {
+ if (element is BasalAction action)
+ {
+ ActionSetter_DepthLevel(action, depthLevel);
+ return true;
+ }
+ else
+ {
+ try
+ {
+ element.SetNamedPropertyValue(nameof(IElement.DepthLevel), depthLevel);
+ return true;
+ }
+ catch { return false; }
+ }
+ }
+ [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_DepthLevel")]
+ private static extern void ActionSetter_DepthLevel(BasalAction action, int value);
+
+ ///
+ /// 设置「IElement」对象的「ParentElement」属性值
+ ///
+ /// 要设置的对象
+ /// 属性值
+ /// 如果设置失败则返回「False」
+ public static bool Help_Setter_ParentElement(this IElement element, IElement? parent)
+ {
+ if (element is BasalAction action)
+ {
+ ActionSetter_ParentElement(action, parent);
+ return true;
+ }
+ else
+ {
+ try
+ {
+ element.SetNamedPropertyValue(nameof(IElement.ParentElement), parent);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+ [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_ParentElement")]
+ private static extern void ActionSetter_ParentElement(BasalAction action, IElement? value);
+ }
+}
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/RuntimeHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/RuntimeHelper.cs
new file mode 100644
index 0000000..6b79481
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/Helpers/RuntimeHelper.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Deedy.Activity
+{
+ public static partial class Helper
+ {
+ ///
+ /// 校验一个节点是否处于跳过执行逻辑
+ ///
+ /// 要检查的节点
+ /// 是否需要跳过执行过程
+ public static bool IsNeedBypassing(this IActionElement element)
+ {
+ if (element == null) return false;
+ var parent = element.ParentElement;
+ while (parent != null)
+ {
+ if (parent is IPassable passable)
+ return passable.IsBypassing;
+ else parent = parent.ParentElement;
+ }
+ return false;
+ }
+ }
+}
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs
new file mode 100644
index 0000000..2c43098
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows;
+
+namespace Deedy.Activity
+{
+ public static partial class Helper
+ {
+ ///
+ /// 拖放装饰层的集合
+ ///
+ 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);
+ }
+ }
+}
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
new file mode 100644
index 0000000..625f3cd
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Deedy.Activity.Helpers
+{
+ public static partial class Helper
+ {
+ }
+}
diff --git a/DeedyDesigner/Deedy.Activity/IElement.cs b/DeedyDesigner/Deedy.Activity/IElement.cs
index f4193de..e347939 100644
--- a/DeedyDesigner/Deedy.Activity/IElement.cs
+++ b/DeedyDesigner/Deedy.Activity/IElement.cs
@@ -40,17 +40,17 @@ namespace Deedy.Activity
container.Remove(this);
container.Append(this);
//this.SetNamedPropertyValue(nameof(ParentElement), element);
- this.Setter_ParentElement(element);
+ this.Help_Setter_ParentElement(element);
}
}
}
else
{
//this.SetNamedPropertyValue(nameof(ParentElement), element);
- this.Setter_ParentElement(element);
+ this.Help_Setter_ParentElement(element);
}
//this.SetNamedPropertyValue(nameof(DepthLevel), (this.ParentElement?.DepthLevel ?? 0) + 1);
- this.Setter_DepthLevel((this.ParentElement?.DepthLevel ?? 0) + 1);
+ this.Help_Setter_DepthLevel((this.ParentElement?.DepthLevel ?? 0) + 1);
}
///
/// 断开自身与父级节点的链接关系
@@ -59,9 +59,9 @@ namespace Deedy.Activity
{
(this.ParentElement as IContainerElement)?.Remove(this);
//this.SetNamedPropertyValue(nameof(ParentElement), null);
- this.Setter_ParentElement(null);
+ this.Help_Setter_ParentElement(null);
//this.SetNamedPropertyValue(nameof(DepthLevel), 0);
- this.Setter_DepthLevel(0);
+ this.Help_Setter_DepthLevel(0);
}
///
/// 构建结构树,设置层级:并且完成参数映射的刷新
@@ -69,7 +69,7 @@ namespace Deedy.Activity
///
public new void ReadyToWorking(IElement? element = null, Output? output = null)
{
- this.BuildParamMapping(output);
+ this.Help_BuildParamMapping(output);
this.LinkTo(element);
if (this is IContainerElement container)