重新规划Helper类的功能与结构
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
/// <summary>
|
||||
/// 如果类型上没有组装规则,则认为不允许组装,否则按照组装规则处理
|
||||
/// </summary>
|
||||
/// <param name="element">要进行组装检查的单元实例</param>
|
||||
/// <returns>是否允许组装</returns>
|
||||
public bool CombineChecking(IElement element, out DragDropEffects effects) => this.Help_CombineChecking(element, out effects);
|
||||
public bool CombineChecking(IElement element, out DragDropEffects effects);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -82,271 +82,5 @@ namespace Deedy.Activity
|
||||
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 帮助一个IElement节点构建参数映射表
|
||||
/// </summary>
|
||||
/// <param name="element">需要构建参数映射表的Element节点</param>
|
||||
/// <param name="output">消息输出器</param>
|
||||
public static void BuildParamMapping(this IElement element, Output? output = null)
|
||||
{
|
||||
//
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个元素插入到当前节点前方「前提:当前节点的父级必须是可变容器节点」
|
||||
/// </summary>
|
||||
/// <param name="element">当前节点</param>
|
||||
/// <param name="insertion">待插入的节点</param>
|
||||
public static void InsertElementToFore(this IElement element, IElement insertion)
|
||||
{
|
||||
if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个元素插入到当前节点后方「前提:当前节点的父级必须是可变容器节点」
|
||||
/// </summary>
|
||||
/// <param name="element">当前节点</param>
|
||||
/// <param name="insertion">待插入的节点</param>
|
||||
public static void InsertElementAtRear(this IElement element, IElement insertion)
|
||||
{
|
||||
if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
|
||||
}
|
||||
/// <summary>
|
||||
/// 将当前节点从父节点中移除
|
||||
/// </summary>
|
||||
/// <param name="element">要移除的元素</param>
|
||||
public static void RemoveFromParent(this IElement element)
|
||||
{
|
||||
if (element != null && element.ParentElement is IContainerElement container) container.Remove(element);
|
||||
}
|
||||
private static readonly Dictionary<Type, (List<CombineRule_AllowTypeAttribute>, List<CombineRule_RejectTypeAttribute>)> StaticField_CombineRules = [];
|
||||
/// <summary>
|
||||
/// 查询可动态组装集合的组合规则
|
||||
/// </summary>
|
||||
/// <param name="element">要查询的元素</param>
|
||||
/// <param name="allowTypes">允许规则集合</param>
|
||||
/// <param name="rejectTypes">禁止规则集合</param>
|
||||
public static void GetCombineRules(this IContainerElement element,
|
||||
ref List<CombineRule_AllowTypeAttribute> allowTypes,
|
||||
ref List<CombineRule_RejectTypeAttribute> rejectTypes)
|
||||
{
|
||||
if (element == null) return;
|
||||
Type type = element.GetType();
|
||||
if (!StaticField_CombineRules.ContainsKey(type))
|
||||
{
|
||||
var _AllowTypes = new List<CombineRule_AllowTypeAttribute>();
|
||||
var _RejectTypes = new List<CombineRule_RejectTypeAttribute>();
|
||||
|
||||
var clearRule = type.GetCustomAttribute<CombineRule_ClearInheritedAttribute>(false);
|
||||
if (clearRule != null)
|
||||
{
|
||||
var allowRules = type.GetCustomAttributes<CombineRule_AllowTypeAttribute>(false);
|
||||
foreach (var rule in allowRules) _AllowTypes.Add(rule);
|
||||
var rejectRules = type.GetCustomAttributes<CombineRule_RejectTypeAttribute>(false);
|
||||
foreach (var rule in rejectRules) _RejectTypes.Add(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
//沿着继承链查找具备「CombineRule_ClearInheritedAttribute」特性的类型,获取组装属性
|
||||
List<Type> types = [];
|
||||
Type? baseType = type.BaseType;
|
||||
while (baseType != null)
|
||||
{
|
||||
types.Add(baseType);
|
||||
clearRule = baseType.GetCustomAttribute<CombineRule_ClearInheritedAttribute>(false);
|
||||
if (clearRule != null) break;
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
foreach (var ruleType in types)
|
||||
{
|
||||
var aRules = ruleType.GetCustomAttributes<CombineRule_AllowTypeAttribute>(false);
|
||||
foreach (var rule in aRules) _AllowTypes.Add(rule);
|
||||
var rRules = ruleType.GetCustomAttributes<CombineRule_RejectTypeAttribute>(false);
|
||||
foreach (var rule in rRules) _RejectTypes.Add(rule);
|
||||
}
|
||||
}
|
||||
StaticField_CombineRules.Add(type, (allowTypes, rejectTypes));
|
||||
}
|
||||
|
||||
(List<CombineRule_AllowTypeAttribute> allowTypes, List<CombineRule_RejectTypeAttribute> rejectTypes) rules
|
||||
= StaticField_CombineRules[type];
|
||||
allowTypes.AddRange(rules.allowTypes);
|
||||
rejectTypes.AddRange(rules.rejectTypes);
|
||||
}
|
||||
/// <summary>
|
||||
/// 校验一个节点是否处于跳过执行逻辑
|
||||
/// </summary>
|
||||
/// <param name="element">要检查的节点</param>
|
||||
/// <returns>是否需要跳过执行过程</returns>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 查找指定类型的祖辈元素
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要查找的祖非类型</typeparam>
|
||||
/// <param name="element">查找的起点</param>
|
||||
/// <param name="level">查找的层级,默认1级</param>
|
||||
/// <returns>如果找到根元素也未找到则返回「null」</returns>
|
||||
public static T? FindAncestorElement<T>(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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 调整子节点的退出线位置
|
||||
/// </summary>
|
||||
/// <param name="container">要调整的带退出线容器</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置「IElement」对象的「DepthLevel」属性值
|
||||
/// </summary>
|
||||
/// <param name="element">要设置的对象</param>
|
||||
/// <param name="depthLevel">层级深度</param>
|
||||
/// <returns>如果设置失败则返回「False」</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// 设置「IElement」对象的「ParentElement」属性值
|
||||
/// </summary>
|
||||
/// <param name="element">要设置的对象</param>
|
||||
/// <param name="parent">属性值</param>
|
||||
/// <returns>如果设置失败则返回「False」</returns>
|
||||
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);
|
||||
/// <summary>
|
||||
/// 拖放装饰层的集合
|
||||
/// </summary>
|
||||
private readonly static ConcurrentDictionary<UIElement, AdornerLayer> AdornerLayers = new();
|
||||
/// <summary>
|
||||
/// 拖放装饰器的集合
|
||||
/// </summary>
|
||||
private readonly static ConcurrentDictionary<UIElement, DragPlacementAdorner> DragAdorners = new();
|
||||
/// <summary>
|
||||
/// 移除一个「UIElement」上的拖放装饰器
|
||||
/// </summary>
|
||||
/// <param name="viewer">目标「UIElement」对象</param>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新一个「UIElement」上的拖放装饰器
|
||||
/// </summary>
|
||||
/// <param name="viewer">目标「UIElement」对象</param>
|
||||
/// <param name="dock">画线位置,「null」表示画4面框线</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Type, (List<CombineRule_AllowTypeAttribute>, List<CombineRule_RejectTypeAttribute>)> StaticField_CombineRules = [];
|
||||
/// <summary>
|
||||
/// 查询可动态组装集合的组合规则
|
||||
/// </summary>
|
||||
/// <param name="element">要查询的元素</param>
|
||||
/// <param name="allowTypes">允许规则集合</param>
|
||||
/// <param name="rejectTypes">禁止规则集合</param>
|
||||
public static void Help_GetCombineRules(this IContainerElement element,
|
||||
ref List<CombineRule_AllowTypeAttribute> allowTypes,
|
||||
ref List<CombineRule_RejectTypeAttribute> rejectTypes)
|
||||
{
|
||||
if (element == null) return;
|
||||
Type type = element.GetType();
|
||||
if (!StaticField_CombineRules.ContainsKey(type))
|
||||
{
|
||||
var _AllowTypes = new List<CombineRule_AllowTypeAttribute>();
|
||||
var _RejectTypes = new List<CombineRule_RejectTypeAttribute>();
|
||||
|
||||
var clearRule = type.GetCustomAttribute<CombineRule_ClearInheritedAttribute>(false);
|
||||
if (clearRule != null)
|
||||
{
|
||||
var allowRules = type.GetCustomAttributes<CombineRule_AllowTypeAttribute>(false);
|
||||
foreach (var rule in allowRules) _AllowTypes.Add(rule);
|
||||
var rejectRules = type.GetCustomAttributes<CombineRule_RejectTypeAttribute>(false);
|
||||
foreach (var rule in rejectRules) _RejectTypes.Add(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
//沿着继承链查找具备「CombineRule_ClearInheritedAttribute」特性的类型,获取组装属性
|
||||
List<Type> types = [];
|
||||
Type? baseType = type.BaseType;
|
||||
while (baseType != null)
|
||||
{
|
||||
types.Add(baseType);
|
||||
clearRule = baseType.GetCustomAttribute<CombineRule_ClearInheritedAttribute>(false);
|
||||
if (clearRule != null) break;
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
foreach (var ruleType in types)
|
||||
{
|
||||
var aRules = ruleType.GetCustomAttributes<CombineRule_AllowTypeAttribute>(false);
|
||||
foreach (var rule in aRules) _AllowTypes.Add(rule);
|
||||
var rRules = ruleType.GetCustomAttributes<CombineRule_RejectTypeAttribute>(false);
|
||||
foreach (var rule in rRules) _RejectTypes.Add(rule);
|
||||
}
|
||||
}
|
||||
StaticField_CombineRules.Add(type, (allowTypes, rejectTypes));
|
||||
}
|
||||
|
||||
(List<CombineRule_AllowTypeAttribute> allowTypes, List<CombineRule_RejectTypeAttribute> rejectTypes) rules
|
||||
= StaticField_CombineRules[type];
|
||||
allowTypes.AddRange(rules.allowTypes);
|
||||
rejectTypes.AddRange(rules.rejectTypes);
|
||||
}
|
||||
/// <summary>
|
||||
/// 如果类型上没有组装规则,则认为不允许组装,否则按照组装规则处理
|
||||
/// </summary>
|
||||
/// <param name="container">要校验的可动态组装容器</param>
|
||||
/// <param name="element">要进行组装检查的单元实例</param>
|
||||
/// <param name="effects">校验结果</param>
|
||||
/// <returns>是否允许组装</returns>
|
||||
public static bool Help_CombineChecking(this IContainerElement container, IElement element, out DragDropEffects effects)
|
||||
{
|
||||
DragDropEffects resultEffects = DragDropEffects.None;
|
||||
List<CombineRule_AllowTypeAttribute> _AllowTypes = [];
|
||||
List<CombineRule_RejectTypeAttribute> _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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个元素插入到可变容器的指定位置
|
||||
/// </summary>
|
||||
/// <param name="this">可变元素容器</param>
|
||||
/// <param name="element">要插入的元素</param>
|
||||
/// <param name="index">要插入的位置</param>
|
||||
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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个元素移动到容器的指定位置
|
||||
/// </summary>
|
||||
/// <param name="this">可变元素容器</param>
|
||||
/// <param name="element">要移动的元素</param>
|
||||
/// <param name="index">要移动到的位置</param>
|
||||
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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 帮助一个IElement节点构建参数映射表
|
||||
/// </summary>
|
||||
/// <param name="element">需要构建参数映射表的Element节点</param>
|
||||
/// <param name="output">消息输出器</param>
|
||||
public static void Help_BuildParamMapping(this IElement element, Output? output = null)
|
||||
{
|
||||
//TODO:构建元素的参数映射表
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个元素插入到当前节点前方「前提:当前节点的父级必须是可变容器节点」
|
||||
/// </summary>
|
||||
/// <param name="element">当前节点</param>
|
||||
/// <param name="insertion">待插入的节点</param>
|
||||
public static void Help_InsertElementToFore(this IElement element, IElement insertion)
|
||||
{
|
||||
if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
|
||||
//TODO:在当前节点前方插入新节点
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个元素插入到当前节点后方「前提:当前节点的父级必须是可变容器节点」
|
||||
/// </summary>
|
||||
/// <param name="element">当前节点</param>
|
||||
/// <param name="insertion">待插入的节点</param>
|
||||
public static void Help_InsertElementAtRear(this IElement element, IElement insertion)
|
||||
{
|
||||
if (element == null || insertion == null || insertion.ParentElement is ICombinedElement) return;
|
||||
//TODO:在当前节点的后方插入新节点
|
||||
}
|
||||
/// <summary>
|
||||
/// 将当前节点从父节点中移除
|
||||
/// </summary>
|
||||
/// <param name="element">要移除的元素</param>
|
||||
public static void Help_RemoveFromParent(this IElement element)
|
||||
{
|
||||
if (element != null && element.ParentElement is IContainerElement container) container.Remove(element);
|
||||
//TODO:将当前节点从自身的父级节点中移除
|
||||
}
|
||||
/// <summary>
|
||||
/// 调整子节点的退出线位置
|
||||
/// </summary>
|
||||
/// <param name="container">要调整的带退出线容器</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
DeedyDesigner/Deedy.Activity/Helpers/ActivityHelper.cs
Normal file
13
DeedyDesigner/Deedy.Activity/Helpers/ActivityHelper.cs
Normal file
@@ -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:管理附加属性与准备方法
|
||||
}
|
||||
}
|
||||
95
DeedyDesigner/Deedy.Activity/Helpers/ElementHelper.cs
Normal file
95
DeedyDesigner/Deedy.Activity/Helpers/ElementHelper.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 查找指定类型的祖辈元素
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要查找的祖非类型</typeparam>
|
||||
/// <param name="element">查找的起点</param>
|
||||
/// <param name="level">查找的层级,默认1级</param>
|
||||
/// <returns>如果找到根元素也未找到则返回「null」</returns>
|
||||
public static T? FindAncestorElement<T>(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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置「IElement」对象的「DepthLevel」属性值
|
||||
/// </summary>
|
||||
/// <param name="element">要设置的对象</param>
|
||||
/// <param name="depthLevel">层级深度</param>
|
||||
/// <returns>如果设置失败则返回「False」</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// 设置「IElement」对象的「ParentElement」属性值
|
||||
/// </summary>
|
||||
/// <param name="element">要设置的对象</param>
|
||||
/// <param name="parent">属性值</param>
|
||||
/// <returns>如果设置失败则返回「False」</returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
29
DeedyDesigner/Deedy.Activity/Helpers/RuntimeHelper.cs
Normal file
29
DeedyDesigner/Deedy.Activity/Helpers/RuntimeHelper.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 校验一个节点是否处于跳过执行逻辑
|
||||
/// </summary>
|
||||
/// <param name="element">要检查的节点</param>
|
||||
/// <returns>是否需要跳过执行过程</returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs
Normal file
62
DeedyDesigner/Deedy.Activity/Helpers/ViewerHelper.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 拖放装饰层的集合
|
||||
/// </summary>
|
||||
private readonly static ConcurrentDictionary<UIElement, AdornerLayer> AdornerLayers = new();
|
||||
/// <summary>
|
||||
/// 拖放装饰器的集合
|
||||
/// </summary>
|
||||
private readonly static ConcurrentDictionary<UIElement, DragPlacementAdorner> DragAdorners = new();
|
||||
/// <summary>
|
||||
/// 移除一个「UIElement」上的拖放装饰器
|
||||
/// </summary>
|
||||
/// <param name="viewer">目标「UIElement」对象</param>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新一个「UIElement」上的拖放装饰器
|
||||
/// </summary>
|
||||
/// <param name="viewer">目标「UIElement」对象</param>
|
||||
/// <param name="dock">画线位置,「null」表示画4面框线</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
Normal file
12
DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
Normal file
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 断开自身与父级节点的链接关系
|
||||
@@ -59,9 +59,9 @@ namespace Deedy.Activity
|
||||
{
|
||||
(this.ParentElement as IContainerElement)?.Remove(this);
|
||||
//this.SetNamedPropertyValue<IElement?>(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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 构建结构树,设置层级:并且完成参数映射的刷新
|
||||
@@ -69,7 +69,7 @@ namespace Deedy.Activity
|
||||
/// <param name="parent"></param>
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user