mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-05-03 22:01:27 +08:00
添加画布信息视图
This commit is contained in:
@@ -65,16 +65,6 @@ namespace Serein.Library
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserInfo
|
|
||||||
{
|
|
||||||
public string Name;
|
|
||||||
public int Id;
|
|
||||||
public string[] PhoneNums;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成的节点控件
|
/// 生成的节点控件
|
||||||
@@ -109,11 +99,7 @@ namespace Serein.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("base")]
|
[Description("base")]
|
||||||
ExpCondition,
|
ExpCondition,
|
||||||
/// <summary>
|
|
||||||
/// 条件节点区域
|
|
||||||
/// </summary>
|
|
||||||
[Description("base")]
|
|
||||||
ConditionRegion,
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 全局数据
|
/// 全局数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -129,6 +115,15 @@ namespace Serein.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("base")]
|
[Description("base")]
|
||||||
NetScript,
|
NetScript,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 流程调用节点(流程图公开的节点)
|
||||||
|
/// </summary>
|
||||||
|
[Description("base")]
|
||||||
|
FlowCall,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ namespace Serein.Library
|
|||||||
public static NodeInfo ToInfo(this NodeModelBase nodeModel)
|
public static NodeInfo ToInfo(this NodeModelBase nodeModel)
|
||||||
{
|
{
|
||||||
// if (MethodDetails == null) return null;
|
// if (MethodDetails == null) return null;
|
||||||
|
|
||||||
var trueNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsSucceed].Select(item => item.Guid); // 真分支
|
var trueNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsSucceed].Select(item => item.Guid); // 真分支
|
||||||
var falseNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsFail].Select(item => item.Guid);// 假分支
|
var falseNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsFail].Select(item => item.Guid);// 假分支
|
||||||
var errorNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsError].Select(item => item.Guid);// 异常分支
|
var errorNodes = nodeModel.SuccessorNodes[ConnectionInvokeType.IsError].Select(item => item.Guid);// 异常分支
|
||||||
@@ -103,8 +102,9 @@ namespace Serein.Library
|
|||||||
|
|
||||||
var nodeInfo = new NodeInfo
|
var nodeInfo = new NodeInfo
|
||||||
{
|
{
|
||||||
CanvasGuid = nodeModel.CanvasGuid,
|
CanvasGuid = nodeModel.CanvasDetails.Guid,
|
||||||
Guid = nodeModel.Guid,
|
Guid = nodeModel.Guid,
|
||||||
|
IsPublic = nodeModel.IsPublic,
|
||||||
AssemblyName = nodeModel.MethodDetails.AssemblyName,
|
AssemblyName = nodeModel.MethodDetails.AssemblyName,
|
||||||
MethodName = nodeModel.MethodDetails?.MethodName,
|
MethodName = nodeModel.MethodDetails?.MethodName,
|
||||||
Label = nodeModel.MethodDetails?.MethodAnotherName,
|
Label = nodeModel.MethodDetails?.MethodAnotherName,
|
||||||
@@ -131,18 +131,18 @@ namespace Serein.Library
|
|||||||
/// 从节点信息加载节点
|
/// 从节点信息加载节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodeModel"></param>
|
/// <param name="nodeModel"></param>
|
||||||
|
/// <param name="canvas"></param>
|
||||||
/// <param name="nodeInfo"></param>
|
/// <param name="nodeInfo"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static void LoadInfo(this NodeModelBase nodeModel, NodeInfo nodeInfo)
|
public static void LoadInfo(this NodeModelBase nodeModel, NodeInfo nodeInfo)
|
||||||
{
|
{
|
||||||
nodeModel.CanvasGuid = nodeInfo.CanvasGuid;
|
|
||||||
nodeModel.Guid = nodeInfo.Guid;
|
nodeModel.Guid = nodeInfo.Guid;
|
||||||
nodeModel.Position = nodeInfo.Position ?? new PositionOfUI(0, 0);// 加载位置信息
|
nodeModel.Position = nodeInfo.Position ?? new PositionOfUI(0, 0);// 加载位置信息
|
||||||
var md = nodeModel.MethodDetails; // 当前节点的方法说明
|
var md = nodeModel.MethodDetails; // 当前节点的方法说明
|
||||||
nodeModel.MethodDetails.IsProtectionParameter = nodeInfo.IsProtectionParameter; // 保护参数
|
nodeModel.MethodDetails.IsProtectionParameter = nodeInfo.IsProtectionParameter; // 保护参数
|
||||||
nodeModel.DebugSetting.IsInterrupt = nodeInfo.IsInterrupt; // 是否中断
|
nodeModel.DebugSetting.IsInterrupt = nodeInfo.IsInterrupt; // 是否中断
|
||||||
nodeModel.DebugSetting.IsEnable = nodeInfo.IsEnable; // 是否使能
|
nodeModel.DebugSetting.IsEnable = nodeInfo.IsEnable; // 是否使能
|
||||||
|
nodeModel.IsPublic = nodeInfo.IsPublic; // 是否全局公开
|
||||||
if (md != null)
|
if (md != null)
|
||||||
{
|
{
|
||||||
if (md.ParameterDetailss == null)
|
if (md.ParameterDetailss == null)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Serein.Library.FlowNode;
|
using Serein.Library.FlowNode;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -27,9 +28,21 @@ namespace Serein.Library
|
|||||||
public IFlowEnvironment Env { get; }
|
public IFlowEnvironment Env { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标识画布ID
|
/// 画布拥有的节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo(IsProtection = true)]
|
[PropertyInfo(IsProtection = true)]
|
||||||
|
private System.Collections.ObjectModel.ObservableCollection<NodeModelBase> _nodes = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 画布公开的节点
|
||||||
|
/// </summary>
|
||||||
|
[PropertyInfo(IsProtection = true)]
|
||||||
|
private System.Collections.ObjectModel.ObservableCollection<NodeModelBase> _publicNodes = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标识画布ID
|
||||||
|
/// </summary>
|
||||||
|
[PropertyInfo(IsProtection = false)]
|
||||||
private string _guid;
|
private string _guid;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -54,19 +67,19 @@ namespace Serein.Library
|
|||||||
/// 预览位置X
|
/// 预览位置X
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo(IsNotification = true)]
|
[PropertyInfo(IsNotification = true)]
|
||||||
private double _viewX ;
|
private double _viewX;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 预览位置Y
|
/// 预览位置Y
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo(IsNotification = true)]
|
[PropertyInfo(IsNotification = true)]
|
||||||
private double _viewY ;
|
private double _viewY;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 缩放比例X
|
/// 缩放比例X
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo(IsNotification = true)]
|
[PropertyInfo(IsNotification = true)]
|
||||||
private double _scaleX = 1;
|
private double _scaleX = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 缩放比例Y
|
/// 缩放比例Y
|
||||||
@@ -85,7 +98,7 @@ namespace Serein.Library
|
|||||||
|
|
||||||
public partial class FlowCanvasDetails
|
public partial class FlowCanvasDetails
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Serein.Library
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点基类(数据)
|
/// 节点基类(数据)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NodeProperty(ValuePath = NodeValuePath.None)]
|
[NodeProperty(ValuePath = NodeValuePath.Node)]
|
||||||
public abstract partial class NodeModelBase : IDynamicFlowNode
|
public abstract partial class NodeModelBase : IDynamicFlowNode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,13 +35,11 @@ namespace Serein.Library
|
|||||||
[PropertyInfo(IsProtection = true)]
|
[PropertyInfo(IsProtection = true)]
|
||||||
private NodeControlType _controlType;
|
private NodeControlType _controlType;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 所属画布
|
/// 所属画布
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo(IsProtection = true)]
|
[PropertyInfo(IsProtection = true)]
|
||||||
private string _canvasGuid ;
|
private FlowCanvasDetails _canvasDetails ;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 在画布中的位置
|
/// 在画布中的位置
|
||||||
@@ -56,10 +54,10 @@ namespace Serein.Library
|
|||||||
private string _displayName;
|
private string _displayName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否为起点控件
|
/// 是否公开
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo]
|
[PropertyInfo(IsNotification = true, CustomCodeAtEnd = "NodePublicStateChanged();")]
|
||||||
private bool _isStart;
|
private bool _isPublic;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 附加的调试功能
|
/// 附加的调试功能
|
||||||
@@ -68,7 +66,7 @@ namespace Serein.Library
|
|||||||
private NodeDebugSetting _debugSetting ;
|
private NodeDebugSetting _debugSetting ;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 方法描述。不包含Method与委托,需要通过MethodName从环境中获取委托进行调用。
|
/// 方法描述。包含参数信息。不包含Method与委托,如若需要调用对应的方法,需要通过MethodName从环境中获取委托进行调用。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PropertyInfo(IsProtection = true)]
|
[PropertyInfo(IsProtection = true)]
|
||||||
private MethodDetails _methodDetails ;
|
private MethodDetails _methodDetails ;
|
||||||
@@ -122,7 +120,29 @@ namespace Serein.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<NodeModelBase> ChildrenNode { get; }
|
public List<NodeModelBase> ChildrenNode { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点公开状态发生改变
|
||||||
|
/// </summary>
|
||||||
|
private void NodePublicStateChanged()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (IsPublic)
|
||||||
|
{
|
||||||
|
// 公开节点
|
||||||
|
if (!CanvasDetails.PublicNodes.Contains(this))
|
||||||
|
{
|
||||||
|
CanvasDetails.PublicNodes.Add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 取消公开
|
||||||
|
if (CanvasDetails.PublicNodes.Contains(this))
|
||||||
|
{
|
||||||
|
CanvasDetails.PublicNodes.Remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Serein.Library
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点基类(数据):条件控件,动作控件,条件区域,动作区域
|
/// 节点基类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract partial class NodeModelBase : IDynamicFlowNode
|
public abstract partial class NodeModelBase : IDynamicFlowNode
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -197,6 +197,11 @@ namespace Serein.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Guid { get; set; }
|
public string Guid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否全局公开
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPublic { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点方法所属的程序集名称
|
/// 节点方法所属的程序集名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -24,12 +24,15 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Entity\Base\**" />
|
<Compile Remove="Entity\Base\**" />
|
||||||
<Compile Remove="Http\**" />
|
<Compile Remove="Http\**" />
|
||||||
|
<Compile Remove="Network\Socket\**" />
|
||||||
<Compile Remove="Utils\SerinExpression\**" />
|
<Compile Remove="Utils\SerinExpression\**" />
|
||||||
<EmbeddedResource Remove="Entity\Base\**" />
|
<EmbeddedResource Remove="Entity\Base\**" />
|
||||||
<EmbeddedResource Remove="Http\**" />
|
<EmbeddedResource Remove="Http\**" />
|
||||||
|
<EmbeddedResource Remove="Network\Socket\**" />
|
||||||
<EmbeddedResource Remove="Utils\SerinExpression\**" />
|
<EmbeddedResource Remove="Utils\SerinExpression\**" />
|
||||||
<None Remove="Entity\Base\**" />
|
<None Remove="Entity\Base\**" />
|
||||||
<None Remove="Http\**" />
|
<None Remove="Http\**" />
|
||||||
|
<None Remove="Network\Socket\**" />
|
||||||
<None Remove="Utils\SerinExpression\**" />
|
<None Remove="Utils\SerinExpression\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@@ -51,10 +54,6 @@
|
|||||||
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
|
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Network\Socket\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\LICENSE">
|
<None Include="..\LICENSE">
|
||||||
<Pack>True</Pack>
|
<Pack>True</Pack>
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ namespace Serein.Library.Utils
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public Type Type { get; set; }
|
public Type Type { get; set; }
|
||||||
}
|
}
|
||||||
private const string FlowBaseClassName = "<>$FlowBaseClass!@#";
|
private const string FlowBaseClassName = "@FlowBaseClass";
|
||||||
|
|
||||||
|
|
||||||
public Dictionary<string, List<string>> BuildDependencyTree()
|
public Dictionary<string, List<string>> BuildDependencyTree()
|
||||||
|
|||||||
@@ -54,10 +54,11 @@ namespace Serein.Library.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 同步方式进行调用方法
|
/// 同步方式在UI线程上进行调用方法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uiAction">要执行的UI操作</param>
|
/// <param name="uiAction">要执行的UI操作</param>
|
||||||
public void Invoke(Action uiAction)
|
/// <param name="onException">异常发生时的回调</param>
|
||||||
|
public void Invoke(Action uiAction, Action<Exception> onException = null)
|
||||||
{
|
{
|
||||||
if(context is null && getUiContext != null)
|
if(context is null && getUiContext != null)
|
||||||
{
|
{
|
||||||
@@ -65,7 +66,15 @@ namespace Serein.Library.Utils
|
|||||||
}
|
}
|
||||||
context?.Post(state =>
|
context?.Post(state =>
|
||||||
{
|
{
|
||||||
uiAction?.Invoke();
|
try
|
||||||
|
{
|
||||||
|
uiAction?.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if(onException != null) onException(ex);
|
||||||
|
Debug.WriteLine(ex);
|
||||||
|
}
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,8 +82,9 @@ namespace Serein.Library.Utils
|
|||||||
/// 异步方式进行调用
|
/// 异步方式进行调用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uiAction">要执行的UI操作</param>
|
/// <param name="uiAction">要执行的UI操作</param>
|
||||||
|
/// <param name="onException">异常发生时的回调</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task InvokeAsync(Action uiAction)
|
public Task InvokeAsync(Action uiAction, Action<Exception> onException = null)
|
||||||
{
|
{
|
||||||
if (context is null && getUiContext != null)
|
if (context is null && getUiContext != null)
|
||||||
{
|
{
|
||||||
@@ -92,6 +102,7 @@ namespace Serein.Library.Utils
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
tcs.SetException(ex);
|
tcs.SetException(ex);
|
||||||
|
if (onException != null) onException(ex);
|
||||||
Debug.WriteLine(ex);
|
Debug.WriteLine(ex);
|
||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Serein.Library.Utils.SereinExpression;
|
|||||||
using Serein.NodeFlow.Model;
|
using Serein.NodeFlow.Model;
|
||||||
using Serein.NodeFlow.Tool;
|
using Serein.NodeFlow.Tool;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -52,7 +53,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
NodeMVVMManagement.RegisterModel(NodeControlType.Flipflop, typeof(SingleFlipflopNode)); // 触发器节点
|
NodeMVVMManagement.RegisterModel(NodeControlType.Flipflop, typeof(SingleFlipflopNode)); // 触发器节点
|
||||||
NodeMVVMManagement.RegisterModel(NodeControlType.ExpOp, typeof(SingleExpOpNode)); // 表达式节点
|
NodeMVVMManagement.RegisterModel(NodeControlType.ExpOp, typeof(SingleExpOpNode)); // 表达式节点
|
||||||
NodeMVVMManagement.RegisterModel(NodeControlType.ExpCondition, typeof(SingleConditionNode)); // 条件表达式节点
|
NodeMVVMManagement.RegisterModel(NodeControlType.ExpCondition, typeof(SingleConditionNode)); // 条件表达式节点
|
||||||
NodeMVVMManagement.RegisterModel(NodeControlType.ConditionRegion, typeof(CompositeConditionNode)); // 条件区域
|
//NodeMVVMManagement.RegisterModel(NodeControlType.ConditionRegion, typeof(CompositeConditionNode)); // 条件区域
|
||||||
NodeMVVMManagement.RegisterModel(NodeControlType.GlobalData, typeof(SingleGlobalDataNode)); // 全局数据节点
|
NodeMVVMManagement.RegisterModel(NodeControlType.GlobalData, typeof(SingleGlobalDataNode)); // 全局数据节点
|
||||||
NodeMVVMManagement.RegisterModel(NodeControlType.Script, typeof(SingleScriptNode)); // 脚本节点
|
NodeMVVMManagement.RegisterModel(NodeControlType.Script, typeof(SingleScriptNode)); // 脚本节点
|
||||||
NodeMVVMManagement.RegisterModel(NodeControlType.NetScript, typeof(SingleNetScriptNode)); // 脚本节点
|
NodeMVVMManagement.RegisterModel(NodeControlType.NetScript, typeof(SingleNetScriptNode)); // 脚本节点
|
||||||
@@ -309,36 +310,6 @@ namespace Serein.NodeFlow.Env
|
|||||||
private List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
private List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
/// <summary>
|
|
||||||
/// 起始节点私有属性
|
|
||||||
/// </summary>
|
|
||||||
private NodeModelBase? _startNode = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 起始节点
|
|
||||||
/// </summary>
|
|
||||||
private NodeModelBase? StartNode
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _startNode;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value is null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_startNode is not null)
|
|
||||||
{
|
|
||||||
_startNode.IsStart = false;
|
|
||||||
}
|
|
||||||
value.IsStart = true;
|
|
||||||
_startNode = value;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 流程任务管理
|
/// 流程任务管理
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -385,7 +356,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
SereinEnv.WriteLine(InfoType.WARN, $"画布不存在,停止运行。{canvasGuid}");
|
SereinEnv.WriteLine(InfoType.WARN, $"画布不存在,停止运行。{canvasGuid}");
|
||||||
isBreak = true;
|
isBreak = true;
|
||||||
}
|
}
|
||||||
var count = NodeModels.Values.Count(n => n.CanvasGuid.Equals(canvasGuid));
|
var count = NodeModels.Values.Count(n => n.CanvasDetails.Guid.Equals(canvasGuid));
|
||||||
if(count == 0)
|
if(count == 0)
|
||||||
{
|
{
|
||||||
SereinEnv.WriteLine(InfoType.WARN, $"画布没有节点,停止运行。{canvasGuid}");
|
SereinEnv.WriteLine(InfoType.WARN, $"画布没有节点,停止运行。{canvasGuid}");
|
||||||
@@ -414,7 +385,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var ft = new FlowTask();
|
var ft = new FlowTask();
|
||||||
ft.GetNodes = () => NodeModels.Values.Where(node => node.CanvasGuid.Equals(guid)).ToList();
|
ft.GetNodes = () => NodeModels.Values.Where(node => node.CanvasDetails.Guid.Equals(guid)).ToList();
|
||||||
var startNodeModel = NodeModels.GetValueOrDefault(canvasModel.StartNode);
|
var startNodeModel = NodeModels.GetValueOrDefault(canvasModel.StartNode);
|
||||||
if(startNodeModel is null)
|
if(startNodeModel is null)
|
||||||
{
|
{
|
||||||
@@ -867,7 +838,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
var model = new FlowCanvasDetails(this);
|
var model = new FlowCanvasDetails(this);
|
||||||
model.LoadInfo(info);
|
model.LoadInfo(info);
|
||||||
FlowCanvass.Add(model.Guid, model);
|
FlowCanvass.Add(model.Guid, model);
|
||||||
UIContextOperation.InvokeAsync(() =>
|
UIContextOperation.Invoke(() =>
|
||||||
{
|
{
|
||||||
OnCanvasCreate.Invoke(new CanvasCreateEventArgs(model));
|
OnCanvasCreate.Invoke(new CanvasCreateEventArgs(model));
|
||||||
});
|
});
|
||||||
@@ -886,7 +857,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var count = NodeModels.Values.Count(node => node.CanvasGuid.Equals(canvasGuid));
|
var count = NodeModels.Values.Count(node => node.CanvasDetails.Guid.Equals(canvasGuid));
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
{
|
{
|
||||||
SereinEnv.WriteLine(InfoType.WARN, "无法删除具有节点的画布");
|
SereinEnv.WriteLine(InfoType.WARN, "无法删除具有节点的画布");
|
||||||
@@ -894,7 +865,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
}
|
}
|
||||||
if (FlowCanvass.Remove(canvasGuid))
|
if (FlowCanvass.Remove(canvasGuid))
|
||||||
{
|
{
|
||||||
await UIContextOperation.InvokeAsync(() =>
|
UIContextOperation.Invoke(() =>
|
||||||
{
|
{
|
||||||
OnCanvasRemove.Invoke(new CanvasRemoveEventArgs(canvasGuid));
|
OnCanvasRemove.Invoke(new CanvasRemoveEventArgs(canvasGuid));
|
||||||
});
|
});
|
||||||
@@ -942,10 +913,24 @@ namespace Serein.NodeFlow.Env
|
|||||||
nodeInfo.Guid = string.Empty;
|
nodeInfo.Guid = string.Empty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
if(FlowCanvass.TryGetValue(nodeInfo.CanvasGuid, out var canvasModel))
|
||||||
TryAddNode(nodeModel); // 加载项目时将节点加载到环境中
|
{
|
||||||
|
|
||||||
await UIContextOperation.InvokeAsync(() =>
|
// 节点与画布互相绑定
|
||||||
|
// 需要在UI线程上进行添加,否则会报 “不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改”异常
|
||||||
|
nodeModel.CanvasDetails = canvasModel;
|
||||||
|
UIContextOperation.Invoke(() => canvasModel.Nodes.Add(nodeModel));
|
||||||
|
|
||||||
|
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
||||||
|
TryAddNode(nodeModel); // 加载项目时将节点加载到环境中
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.ERROR, $"加载节点[{nodeInfo.Guid}]时发生异常,画布[{nodeInfo.CanvasGuid}]不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIContextOperation.Invoke(() =>
|
||||||
OnNodeCreate?.Invoke(new NodeCreateEventArgs(nodeInfo.CanvasGuid, nodeModel, nodeInfo.Position))); // 添加到UI上
|
OnNodeCreate?.Invoke(new NodeCreateEventArgs(nodeInfo.CanvasGuid, nodeModel, nodeInfo.Position))); // 添加到UI上
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@@ -971,7 +956,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
var result = nodeContainer.PlaceNode(nodeModel);
|
var result = nodeContainer.PlaceNode(nodeModel);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
await UIContextOperation.InvokeAsync(() => OnNodePlace?.Invoke(
|
UIContextOperation.Invoke(() => OnNodePlace?.Invoke(
|
||||||
new NodePlaceEventArgs(nodeInfo.CanvasGuid, nodeModel.Guid, containerNode.Guid)));
|
new NodePlaceEventArgs(nodeInfo.CanvasGuid, nodeModel.Guid, containerNode.Guid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,7 +1021,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
#region 确定节点之间的参数调用关系
|
#region 确定节点之间的参数调用关系
|
||||||
foreach (var toNode in NodeModels.Values)
|
foreach (var toNode in NodeModels.Values)
|
||||||
{
|
{
|
||||||
var canvasGuid = toNode.CanvasGuid;
|
var canvasGuid = toNode.CanvasDetails.Guid;
|
||||||
if (toNode.MethodDetails.ParameterDetailss == null)
|
if (toNode.MethodDetails.ParameterDetailss == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -1055,9 +1040,9 @@ namespace Serein.NodeFlow.Env
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
await UIContextOperation.InvokeAsync(() =>
|
UIContextOperation.Invoke(() =>
|
||||||
{
|
{
|
||||||
UIContextOperation?.Invoke(() => OnProjectLoaded?.Invoke(new ProjectLoadedEventArgs()));
|
OnProjectLoaded?.Invoke(new ProjectLoadedEventArgs());
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1075,7 +1060,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
PositionOfUI position,
|
PositionOfUI position,
|
||||||
MethodDetailsInfo? methodDetailsInfo = null)
|
MethodDetailsInfo? methodDetailsInfo = null)
|
||||||
{
|
{
|
||||||
if (!TryGetCanvasModel(canvasGuid,out var cavnasModel))
|
if (!TryGetCanvasModel(canvasGuid,out var canvasModel))
|
||||||
{
|
{
|
||||||
return Task.FromResult<NodeInfo>(null);
|
return Task.FromResult<NodeInfo>(null);
|
||||||
}
|
}
|
||||||
@@ -1097,9 +1082,9 @@ namespace Serein.NodeFlow.Env
|
|||||||
return Task.FromResult<NodeInfo>(null);
|
return Task.FromResult<NodeInfo>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nodeModel.CanvasDetails = canvasModel;
|
||||||
|
canvasModel.Nodes.Add(nodeModel); // 节点与画布互相绑定
|
||||||
TryAddNode(nodeModel);
|
TryAddNode(nodeModel);
|
||||||
nodeModel.CanvasGuid = canvasGuid; // 设置所属于的画布
|
|
||||||
nodeModel.Position = position; // 设置位置
|
nodeModel.Position = position; // 设置位置
|
||||||
|
|
||||||
// 通知UI更改
|
// 通知UI更改
|
||||||
@@ -1107,9 +1092,9 @@ namespace Serein.NodeFlow.Env
|
|||||||
|
|
||||||
// 因为需要UI先布置了元素,才能通知UI变更特效
|
// 因为需要UI先布置了元素,才能通知UI变更特效
|
||||||
// 如果不存在流程起始控件,默认设置为流程起始控件
|
// 如果不存在流程起始控件,默认设置为流程起始控件
|
||||||
if (cavnasModel.StartNode is null)
|
if (canvasModel.StartNode is null)
|
||||||
{
|
{
|
||||||
SetStartNode(cavnasModel, nodeModel);
|
SetStartNode(canvasModel, nodeModel);
|
||||||
}
|
}
|
||||||
var nodeInfo = nodeModel.ToInfo();
|
var nodeInfo = nodeModel.ToInfo();
|
||||||
return Task.FromResult(nodeInfo);
|
return Task.FromResult(nodeInfo);
|
||||||
@@ -1147,7 +1132,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
var result = nodeContainer.PlaceNode(nodeModel); // 放置在容器节点
|
var result = nodeContainer.PlaceNode(nodeModel); // 放置在容器节点
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_ = UIContextOperation?.InvokeAsync(() =>
|
UIContextOperation.Invoke(() =>
|
||||||
{
|
{
|
||||||
OnNodePlace?.Invoke(new NodePlaceEventArgs(canvasGuid, nodeGuid, containerNodeGuid)); // 通知UI更改节点放置位置
|
OnNodePlace?.Invoke(new NodePlaceEventArgs(canvasGuid, nodeGuid, containerNodeGuid)); // 通知UI更改节点放置位置
|
||||||
});
|
});
|
||||||
@@ -1179,7 +1164,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
var result = nodeContainer.TakeOutNode(nodeModel); // 从容器节点取出
|
var result = nodeContainer.TakeOutNode(nodeModel); // 从容器节点取出
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
_ = UIContextOperation?.InvokeAsync(() =>
|
UIContextOperation.Invoke(() =>
|
||||||
{
|
{
|
||||||
OnNodeTakeOut?.Invoke(new NodeTakeOutEventArgs(canvasGuid, nodeGuid)); // 重新放置在画布上
|
OnNodeTakeOut?.Invoke(new NodeTakeOutEventArgs(canvasGuid, nodeGuid)); // 重新放置在画布上
|
||||||
});
|
});
|
||||||
@@ -1198,7 +1183,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
/// <exception cref="NotImplementedException"></exception>
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
public async Task<bool> RemoveNodeAsync(string canvasGuid, string nodeGuid)
|
public async Task<bool> RemoveNodeAsync(string canvasGuid, string nodeGuid)
|
||||||
{
|
{
|
||||||
if (!FlowCanvass.ContainsKey(canvasGuid))
|
if (!TryGetCanvasModel(canvasGuid,out var canvasModel))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1247,10 +1232,12 @@ namespace Serein.NodeFlow.Env
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 从集合中移除节点
|
|
||||||
|
// 从集合中移除节点,解除与画布的绑定关系
|
||||||
NodeModels.Remove(nodeGuid);
|
NodeModels.Remove(nodeGuid);
|
||||||
|
UIContextOperation?.Invoke(() => canvasModel.Nodes.Remove(remoteNode));
|
||||||
|
|
||||||
UIContextOperation?.Invoke(() => OnNodeRemove?.Invoke(new NodeRemoveEventArgs(canvasGuid, nodeGuid)));
|
UIContextOperation?.Invoke(() => OnNodeRemove?.Invoke(new NodeRemoveEventArgs(canvasGuid, nodeGuid)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1752,7 +1739,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
{
|
{
|
||||||
await UIContextOperation.InvokeAsync(() => OnNodeConnectChange?.Invoke(
|
UIContextOperation.Invoke(() => OnNodeConnectChange?.Invoke(
|
||||||
new NodeConnectChangeEventArgs(
|
new NodeConnectChangeEventArgs(
|
||||||
canvasGuid,
|
canvasGuid,
|
||||||
fromNode.Guid,
|
fromNode.Guid,
|
||||||
@@ -1785,7 +1772,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
{
|
{
|
||||||
await UIContextOperation.InvokeAsync(() => OnNodeConnectChange?.Invoke(
|
UIContextOperation.Invoke(() => OnNodeConnectChange?.Invoke(
|
||||||
new NodeConnectChangeEventArgs(
|
new NodeConnectChangeEventArgs(
|
||||||
canvasGuid,
|
canvasGuid,
|
||||||
fromNode.Guid,
|
fromNode.Guid,
|
||||||
@@ -1807,6 +1794,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
{
|
{
|
||||||
nodeModel.Guid ??= Guid.NewGuid().ToString();
|
nodeModel.Guid ??= Guid.NewGuid().ToString();
|
||||||
NodeModels.TryAdd(nodeModel.Guid, nodeModel);
|
NodeModels.TryAdd(nodeModel.Guid, nodeModel);
|
||||||
|
|
||||||
|
|
||||||
// 如果是触发器,则需要添加到专属集合中
|
// 如果是触发器,则需要添加到专属集合中
|
||||||
if (nodeModel is SingleFlipflopNode flipflopNode)
|
if (nodeModel is SingleFlipflopNode flipflopNode)
|
||||||
@@ -2005,7 +1993,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
}
|
}
|
||||||
toNode.MethodDetails.ParameterDetailss[argIndex].ArgDataSourceNodeGuid = fromNode.Guid;
|
toNode.MethodDetails.ParameterDetailss[argIndex].ArgDataSourceNodeGuid = fromNode.Guid;
|
||||||
toNode.MethodDetails.ParameterDetailss[argIndex].ArgDataSourceType = connectionArgSourceType;
|
toNode.MethodDetails.ParameterDetailss[argIndex].ArgDataSourceType = connectionArgSourceType;
|
||||||
await UIContextOperation.InvokeAsync(() =>
|
UIContextOperation.Invoke(() =>
|
||||||
OnNodeConnectChange?.Invoke(
|
OnNodeConnectChange?.Invoke(
|
||||||
new NodeConnectChangeEventArgs(
|
new NodeConnectChangeEventArgs(
|
||||||
canvasGuid,
|
canvasGuid,
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ namespace Serein.NodeFlow.Env
|
|||||||
public UIContextOperation UIContextOperation { get; }
|
public UIContextOperation UIContextOperation { get; }
|
||||||
public NodeMVVMManagement NodeMVVMManagement { get; }
|
public NodeMVVMManagement NodeMVVMManagement { get; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运行环境加载的画布集合
|
||||||
|
/// </summary>
|
||||||
|
private Dictionary<string, FlowCanvasDetails> FlowCanvass { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标示是否正在加载项目
|
/// 标示是否正在加载项目
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -893,7 +899,11 @@ namespace Serein.NodeFlow.Env
|
|||||||
|
|
||||||
//MethodDetailss.TryGetValue(methodDetailsInfo.MethodName, out var methodDetails);// 加载项目时尝试获取方法信息
|
//MethodDetailss.TryGetValue(methodDetailsInfo.MethodName, out var methodDetails);// 加载项目时尝试获取方法信息
|
||||||
var nodeModel = FlowNodeExtension.CreateNode(this, nodeControlType, methodDetails); // 远程环境下加载节点
|
var nodeModel = FlowNodeExtension.CreateNode(this, nodeControlType, methodDetails); // 远程环境下加载节点
|
||||||
nodeModel.LoadInfo(nodeInfo);
|
|
||||||
|
if (FlowCanvass.TryGetValue(nodeInfo.CanvasGuid, out var canvasModel))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
||||||
TryAddNode(nodeModel);
|
TryAddNode(nodeModel);
|
||||||
IsLoadingNode = false;
|
IsLoadingNode = false;
|
||||||
|
|
||||||
@@ -1214,6 +1224,10 @@ namespace Serein.NodeFlow.Env
|
|||||||
nodeInfo.Guid = string.Empty;
|
nodeInfo.Guid = string.Empty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FlowCanvass.TryGetValue(nodeInfo.CanvasGuid, out var canvasModel))
|
||||||
|
{
|
||||||
|
}
|
||||||
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
nodeModel.LoadInfo(nodeInfo); // 创建节点model
|
||||||
TryAddNode(nodeModel); // 加载项目时将节点加载到环境中
|
TryAddNode(nodeModel); // 加载项目时将节点加载到环境中
|
||||||
|
|
||||||
@@ -1300,7 +1314,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
if (!string.IsNullOrEmpty(pd.ArgDataSourceNodeGuid)
|
if (!string.IsNullOrEmpty(pd.ArgDataSourceNodeGuid)
|
||||||
&& NodeModels.TryGetValue(pd.ArgDataSourceNodeGuid, out var fromNode))
|
&& NodeModels.TryGetValue(pd.ArgDataSourceNodeGuid, out var fromNode))
|
||||||
{
|
{
|
||||||
var canvasGuid = toNode.CanvasGuid;
|
var canvasGuid = toNode.CanvasDetails.Guid;
|
||||||
UIContextOperation?.Invoke(() =>
|
UIContextOperation?.Invoke(() =>
|
||||||
OnNodeConnectChange?.Invoke(
|
OnNodeConnectChange?.Invoke(
|
||||||
new NodeConnectChangeEventArgs(
|
new NodeConnectChangeEventArgs(
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ namespace Serein.NodeFlow
|
|||||||
{
|
{
|
||||||
var env = WorkOptions.Environment;
|
var env = WorkOptions.Environment;
|
||||||
var flipflopNodes = flow.GetNodes().Where(item => item is SingleFlipflopNode node
|
var flipflopNodes = flow.GetNodes().Where(item => item is SingleFlipflopNode node
|
||||||
&& !node.IsStart
|
|
||||||
&& node.DebugSetting.IsEnable
|
&& node.DebugSetting.IsEnable
|
||||||
&& node.NotExitPreviousNode())
|
&& node.NotExitPreviousNode())
|
||||||
.Select(item => (SingleFlipflopNode)item);
|
.Select(item => (SingleFlipflopNode)item);
|
||||||
|
|||||||
33
NodeFlow/Model/SingleFlowCallNode.cs
Normal file
33
NodeFlow/Model/SingleFlowCallNode.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Serein.Library;
|
||||||
|
using Serein.Library.Api;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.NodeFlow.Model
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 流程调用节点
|
||||||
|
/// </summary>
|
||||||
|
public class SingleFlowCallNode : NodeModelBase
|
||||||
|
{
|
||||||
|
public SingleFlowCallNode(IFlowEnvironment environment) : base(environment)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 需要调用其它流程图中的某个节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override async Task<FlowResult> ExecutingAsync(IDynamicContext context, CancellationToken token)
|
||||||
|
{
|
||||||
|
await base.ExecutingAsync(context, token);
|
||||||
|
return new FlowResult(this, context, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,7 +96,7 @@ namespace Serein.NodeFlow.Model
|
|||||||
{
|
{
|
||||||
foreach (var nodeModel in ChildrenNode)
|
foreach (var nodeModel in ChildrenNode)
|
||||||
{
|
{
|
||||||
await nodeModel.Env.TakeOutNodeToContainerAsync(nodeModel.CanvasGuid, nodeModel.Guid);
|
await nodeModel.Env.TakeOutNodeToContainerAsync(nodeModel.CanvasDetails.Guid, nodeModel.Guid);
|
||||||
}
|
}
|
||||||
DataNode = null;
|
DataNode = null;
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ namespace Serein.NodeFlow.Model
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 移除数据节点
|
// 移除数据节点
|
||||||
_ = this.Env.RemoveNodeAsync(DataNode.CanvasGuid, DataNode.Guid);
|
_ = this.Env.RemoveNodeAsync(DataNode.CanvasDetails.Guid, DataNode.Guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Serein.Library
|
|||||||
public sealed class PropertyInfoAttribute : Attribute
|
public sealed class PropertyInfoAttribute : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否通知UI
|
/// 是否通知远程环境(如果在远程环境下)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsNotification = false;
|
public bool IsNotification = false;
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace Serein.Workbench
|
|||||||
collection.AddSingleton<FlowEditViewModel>();
|
collection.AddSingleton<FlowEditViewModel>();
|
||||||
|
|
||||||
collection.AddTransient<FlowCanvasViewModel>(); // 画布
|
collection.AddTransient<FlowCanvasViewModel>(); // 画布
|
||||||
|
collection.AddTransient<CanvasInfoViewModel>(); // 画布节点树视图
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddWorkbenchServices(this IServiceCollection collection)
|
public static void AddWorkbenchServices(this IServiceCollection collection)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Serein.Library;
|
||||||
using Serein.Workbench.ViewModels;
|
using Serein.Workbench.ViewModels;
|
||||||
using Serein.Workbench.Views;
|
using Serein.Workbench.Views;
|
||||||
using System;
|
using System;
|
||||||
@@ -19,7 +20,7 @@ namespace Serein.Workbench.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// tab 名称
|
/// tab 名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name
|
/* public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -34,6 +35,10 @@ namespace Serein.Workbench.Models
|
|||||||
OnPropertyChanged(nameof(Name));
|
OnPropertyChanged(nameof(Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private FlowCanvasDetails _model;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -91,7 +91,13 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<StackPanel Grid.Row="4" Background="Azure" Orientation="Horizontal" Margin="3">
|
|
||||||
|
<StackPanel Grid.Row="4" Background="Azure" Orientation="Horizontal" Margin="3">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<CheckBox IsChecked="{Binding NodeModel.IsPublic, Mode=TwoWay}"/>
|
||||||
|
<TextBlock Text="全局公开"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}"/>
|
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}"/>
|
||||||
<TextBlock Text="是否使能"/>
|
<TextBlock Text="是否使能"/>
|
||||||
@@ -107,6 +113,8 @@
|
|||||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsInterrupt, Mode=TwoWay}"/>
|
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsInterrupt, Mode=TwoWay}"/>
|
||||||
<TextBlock Text="中断节点"/>
|
<TextBlock Text="中断节点"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
{
|
{
|
||||||
Canvas.Children.Remove(BezierLine);
|
Canvas.Children.Remove(BezierLine);
|
||||||
var env = Start.MyNode.Env;
|
var env = Start.MyNode.Env;
|
||||||
var canvasGuid = Start.MyNode.CanvasGuid;
|
var canvasGuid = Start.MyNode.CanvasDetails.Guid;
|
||||||
if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke)
|
if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke)
|
||||||
{
|
{
|
||||||
env.RemoveConnectInvokeAsync(canvasGuid, Start.MyNode.Guid, End.MyNode.Guid, InvokeType);
|
env.RemoveConnectInvokeAsync(canvasGuid, Start.MyNode.Guid, End.MyNode.Guid, InvokeType);
|
||||||
|
|||||||
16
Workbench/Node/View/FlowCallNodeControl.xaml
Normal file
16
Workbench/Node/View/FlowCallNodeControl.xaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.FlowCallNodeControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||||
|
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||||
|
xmlns:themes="clr-namespace:Serein.Workbench.Themes"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance vm:FlipflopNodeControlViewModel}">
|
||||||
|
<Grid>
|
||||||
|
<!--选择画布-->
|
||||||
|
<!--选择公开的节点-->
|
||||||
|
</Grid>
|
||||||
|
</local:NodeControlBase>
|
||||||
36
Workbench/Node/View/FlowCallNodeControl.xaml.cs
Normal file
36
Workbench/Node/View/FlowCallNodeControl.xaml.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
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.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Node.View
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FlowCallNodeControl.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class FlowCallNodeControl : NodeControlBase, INodeJunction
|
||||||
|
{
|
||||||
|
public FlowCallNodeControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JunctionControlBase ExecuteJunction => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public JunctionControlBase NextStepJunction => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public JunctionControlBase[] ArgDataJunction => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public JunctionControlBase ReturnDataJunction => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
18
Workbench/Node/ViewModel/FlowCallNodeControlViewModel.cs
Normal file
18
Workbench/Node/ViewModel/FlowCallNodeControlViewModel.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Serein.NodeFlow.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Node.ViewModel
|
||||||
|
{
|
||||||
|
public partial class FlowCallNodeControlViewModel : NodeControlViewModelBase
|
||||||
|
{
|
||||||
|
public new SingleFlowCallNode NodelModel { get; }
|
||||||
|
public FlowCallNodeControlViewModel(SingleFlowCallNode node) : base(node)
|
||||||
|
{
|
||||||
|
this.NodelModel = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,8 @@
|
|||||||
<Compile Remove="Node\Junction\NodeJunctionViewBase.cs" />
|
<Compile Remove="Node\Junction\NodeJunctionViewBase.cs" />
|
||||||
<Compile Remove="Node\NodeBase.cs" />
|
<Compile Remove="Node\NodeBase.cs" />
|
||||||
<Compile Remove="Node\View\ActionRegionControl.xaml.cs" />
|
<Compile Remove="Node\View\ActionRegionControl.xaml.cs" />
|
||||||
|
<Compile Remove="Node\View\ConditionRegionControl.xaml.cs" />
|
||||||
|
<Compile Remove="Node\View\DllControlControl.xaml.cs" />
|
||||||
<Compile Remove="Services\NodeControlService.cs" />
|
<Compile Remove="Services\NodeControlService.cs" />
|
||||||
<Compile Remove="Themes\ConditionControl.xaml.cs" />
|
<Compile Remove="Themes\ConditionControl.xaml.cs" />
|
||||||
<Compile Remove="Themes\ConditionControlModel.cs" />
|
<Compile Remove="Themes\ConditionControlModel.cs" />
|
||||||
@@ -43,6 +45,8 @@
|
|||||||
<Page Remove="MainWindow.xaml" />
|
<Page Remove="MainWindow.xaml" />
|
||||||
<Page Remove="Node\FlipflopRegionControl.xaml" />
|
<Page Remove="Node\FlipflopRegionControl.xaml" />
|
||||||
<Page Remove="Node\View\ActionRegionControl.xaml" />
|
<Page Remove="Node\View\ActionRegionControl.xaml" />
|
||||||
|
<Page Remove="Node\View\ConditionRegionControl.xaml" />
|
||||||
|
<Page Remove="Node\View\DllControlControl.xaml" />
|
||||||
<Page Remove="Themes\ConditionControl.xaml" />
|
<Page Remove="Themes\ConditionControl.xaml" />
|
||||||
<Page Remove="Themes\ConnectionControl.xaml" />
|
<Page Remove="Themes\ConnectionControl.xaml" />
|
||||||
<Page Remove="Themes\ExplicitDataControl.xaml" />
|
<Page Remove="Themes\ExplicitDataControl.xaml" />
|
||||||
|
|||||||
@@ -36,14 +36,31 @@ namespace Serein.Workbench.Services
|
|||||||
/// 添加了节点
|
/// 添加了节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<NodeControlBase> OnCreateNode { get; set; }
|
public Action<NodeControlBase> OnCreateNode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查看的画布发生改变
|
||||||
|
/// </summary>
|
||||||
|
public Action<FlowCanvasView> OnViewCanvasChanged{ get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 创建节点相关的属性
|
#region 创建节点相关的属性
|
||||||
|
|
||||||
|
|
||||||
|
private FlowCanvasView currentSelectCanvas;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前查看的画布
|
/// 当前查看的画布
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FlowCanvasView CurrentSelectCanvas { get; set; }
|
public FlowCanvasView CurrentSelectCanvas { get => currentSelectCanvas; set
|
||||||
|
{
|
||||||
|
if (value == null || value.Equals(currentSelectCanvas))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentSelectCanvas = value;
|
||||||
|
OnViewCanvasChanged?.Invoke(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前拖动的方法信息
|
/// 当前拖动的方法信息
|
||||||
@@ -128,7 +145,7 @@ namespace Serein.Workbench.Services
|
|||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.Flipflop, typeof(FlipflopNodeControl), typeof(FlipflopNodeControlViewModel));
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.Flipflop, typeof(FlipflopNodeControl), typeof(FlipflopNodeControlViewModel));
|
||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.ExpOp, typeof(ExpOpNodeControl), typeof(ExpOpNodeControlViewModel));
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.ExpOp, typeof(ExpOpNodeControl), typeof(ExpOpNodeControlViewModel));
|
||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.ExpCondition, typeof(ConditionNodeControl), typeof(ConditionNodeControlViewModel));
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.ExpCondition, typeof(ConditionNodeControl), typeof(ConditionNodeControlViewModel));
|
||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.ConditionRegion, typeof(ConditionRegionControl), typeof(ConditionRegionNodeControlViewModel));
|
//flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.ConditionRegion, typeof(ConditionRegionControl), typeof(ConditionRegionNodeControlViewModel));
|
||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.GlobalData, typeof(GlobalDataControl), typeof(GlobalDataNodeControlViewModel));
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.GlobalData, typeof(GlobalDataControl), typeof(GlobalDataNodeControlViewModel));
|
||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.Script, typeof(ScriptNodeControl), typeof(ScriptNodeControlViewModel));
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.Script, typeof(ScriptNodeControl), typeof(ScriptNodeControlViewModel));
|
||||||
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.NetScript, typeof(NetScriptNodeControl), typeof(NetScriptNodeControlViewModel));
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.NetScript, typeof(NetScriptNodeControl), typeof(NetScriptNodeControlViewModel));
|
||||||
@@ -648,7 +665,7 @@ namespace Serein.Workbench.Services
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = flowEnvironment.RemoveNodeAsync(model.CanvasGuid, model.Guid);
|
_ = flowEnvironment.RemoveNodeAsync(model.CanvasDetails.Guid, model.Guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -78,14 +78,14 @@ namespace Serein.Workbench.Services
|
|||||||
{
|
{
|
||||||
KeysState[(int)key] = true;
|
KeysState[(int)key] = true;
|
||||||
OnKeyDown?.Invoke(key);
|
OnKeyDown?.Invoke(key);
|
||||||
Debug.WriteLine($"按键按下事件:{key}");
|
//Debug.WriteLine($"按键按下事件:{key}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KeyUp(Key key)
|
public void KeyUp(Key key)
|
||||||
{
|
{
|
||||||
KeysState[(int)key] = false;
|
KeysState[(int)key] = false;
|
||||||
OnKeyUp?.Invoke(key);
|
OnKeyUp?.Invoke(key);
|
||||||
Debug.WriteLine($"按键抬起事件:{key}");
|
//Debug.WriteLine($"按键抬起事件:{key}");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
41
Workbench/ViewModels/CanvasNodeTreeViewModel.cs
Normal file
41
Workbench/ViewModels/CanvasNodeTreeViewModel.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Serein.Library;
|
||||||
|
using Serein.Workbench.Services;
|
||||||
|
using Serein.Workbench.Views;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.ViewModels
|
||||||
|
{
|
||||||
|
internal partial class CanvasInfoViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
private readonly FlowNodeService flowNodeService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 画布数据实体
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private FlowCanvasDetails _model;
|
||||||
|
|
||||||
|
public CanvasInfoViewModel(FlowNodeService flowNodeService)
|
||||||
|
{
|
||||||
|
this.flowNodeService = flowNodeService;
|
||||||
|
this.flowNodeService.OnViewCanvasChanged += OnViewCanvasChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查看的画布发生改变
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flowCanvas"></param>
|
||||||
|
private void OnViewCanvasChanged(FlowCanvasView flowCanvas)
|
||||||
|
{
|
||||||
|
if (flowCanvas.DataContext is FlowCanvasViewModel vm)
|
||||||
|
{
|
||||||
|
Model = vm.Model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,8 +22,11 @@ namespace Serein.Workbench.ViewModels
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class FlowEditViewModel : ObservableObject
|
public partial class FlowEditViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
public ObservableCollection<FlowEditorTabModel> CanvasTabs { get; set; } = [];
|
/// <summary>
|
||||||
|
/// 画布集合
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private ObservableCollection<FlowEditorTabModel> _canvasTabs = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前选择的画布
|
/// 当前选择的画布
|
||||||
@@ -42,11 +45,8 @@ namespace Serein.Workbench.ViewModels
|
|||||||
flowNodeService.OnRemoveFlowCanvasView += OnRemoveFlowCanvasView; // 移除了画布
|
flowNodeService.OnRemoveFlowCanvasView += OnRemoveFlowCanvasView; // 移除了画布
|
||||||
this.PropertyChanged += OnPropertyChanged;
|
this.PropertyChanged += OnPropertyChanged;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void OnPropertyChanged(object? value, PropertyChangedEventArgs e)
|
private void OnPropertyChanged(object? value, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (this.SelectedTab is null) return;
|
if (this.SelectedTab is null) return;
|
||||||
@@ -56,9 +56,13 @@ namespace Serein.Workbench.ViewModels
|
|||||||
#region 响应环境事件
|
#region 响应环境事件
|
||||||
private void OnCreateFlowCanvasView(FlowCanvasView canvas)
|
private void OnCreateFlowCanvasView(FlowCanvasView canvas)
|
||||||
{
|
{
|
||||||
var model = new FlowEditorTabModel(canvas);
|
var tab = new FlowEditorTabModel(canvas);
|
||||||
CanvasTabs.Add(model);
|
if(canvas is IFlowCanvas flowCanvas)
|
||||||
SelectedTab = model;
|
{
|
||||||
|
tab.Model = flowCanvas.Model;
|
||||||
|
}
|
||||||
|
CanvasTabs.Add(tab);
|
||||||
|
SelectedTab = tab;
|
||||||
}
|
}
|
||||||
private void OnRemoveFlowCanvasView(FlowCanvasView canvas)
|
private void OnRemoveFlowCanvasView(FlowCanvasView canvas)
|
||||||
{
|
{
|
||||||
@@ -102,7 +106,7 @@ namespace Serein.Workbench.ViewModels
|
|||||||
if (tab != null)
|
if (tab != null)
|
||||||
{
|
{
|
||||||
tab.IsEditing = false;
|
tab.IsEditing = false;
|
||||||
if(tab.Name != newName && !string.IsNullOrWhiteSpace(newName)) tab.Name = newName; // 名称合法时设置新名称
|
if(tab.Model.Name != newName && !string.IsNullOrWhiteSpace(newName)) tab.Model.Name = newName; // 名称合法时设置新名称
|
||||||
OnPropertyChanged(nameof(CanvasTabs)); // 刷新Tabs集合
|
OnPropertyChanged(nameof(CanvasTabs)); // 刷新Tabs集合
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,25 +15,18 @@ namespace Serein.Workbench.ViewModels
|
|||||||
ServiceProvider = serviceProvider;
|
ServiceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private IServiceProvider GetService()
|
|
||||||
//{
|
|
||||||
// var service = new ServiceCollection();
|
|
||||||
// service.AddSingleton<MainViewModel>();
|
|
||||||
// service.AddSingleton<MainMenuBarViewModel>();
|
|
||||||
// service.AddSingleton<FlowWorkbenchViewModel>();
|
|
||||||
// service.AddSingleton<BaseNodesViewModel>();
|
|
||||||
// service.AddSingleton<FlowLibrarysViewModel>();
|
|
||||||
// service.AddTransient<FlowLibraryMethodDetailssViewModel>();
|
|
||||||
// return service.BuildServiceProvider();
|
|
||||||
//}
|
|
||||||
|
|
||||||
public MainViewModel MainViewModel => App.GetService<MainViewModel>() ?? throw new NotImplementedException();
|
public MainViewModel MainViewModel => App.GetService<MainViewModel>() ?? throw new NotImplementedException();
|
||||||
public MainMenuBarViewModel MainMenuBarViewModel => App.GetService<MainMenuBarViewModel>() ?? throw new NotImplementedException();
|
public MainMenuBarViewModel MainMenuBarViewModel => App.GetService<MainMenuBarViewModel>() ?? throw new NotImplementedException();
|
||||||
public FlowWorkbenchViewModel FlowWorkbenchViewModel => App.GetService<FlowWorkbenchViewModel>() ?? throw new NotImplementedException();
|
public FlowWorkbenchViewModel FlowWorkbenchViewModel => App.GetService<FlowWorkbenchViewModel>() ?? throw new NotImplementedException();
|
||||||
public BaseNodesViewModel BaseNodesViewModel => App.GetService<BaseNodesViewModel>() ?? throw new NotImplementedException();
|
public BaseNodesViewModel BaseNodesViewModel => App.GetService<BaseNodesViewModel>() ?? throw new NotImplementedException();
|
||||||
public FlowLibrarysViewModel FlowLibrarysViewModel => App.GetService<FlowLibrarysViewModel>() ?? throw new NotImplementedException();
|
public FlowLibrarysViewModel FlowLibrarysViewModel => App.GetService<FlowLibrarysViewModel>() ?? throw new NotImplementedException();
|
||||||
public FlowEditViewModel FlowEditViewModel => App.GetService<FlowEditViewModel>() ?? throw new NotImplementedException();
|
public FlowEditViewModel FlowEditViewModel => App.GetService<FlowEditViewModel>() ?? throw new NotImplementedException();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public FlowCanvasViewModel FlowCanvasViewModel => App.GetService<FlowCanvasViewModel>() ?? throw new NotImplementedException();
|
public FlowCanvasViewModel FlowCanvasViewModel => App.GetService<FlowCanvasViewModel>() ?? throw new NotImplementedException();
|
||||||
|
public CanvasInfoViewModel CanvasNodeTreeViewModel => App.GetService<CanvasInfoViewModel>() ?? throw new NotImplementedException();
|
||||||
|
|
||||||
public IServiceProvider ServiceProvider { get; }
|
public IServiceProvider ServiceProvider { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
96
Workbench/Views/CanvasInfoView.xaml
Normal file
96
Workbench/Views/CanvasInfoView.xaml
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<UserControl x:Class="Serein.Workbench.Views.CanvasInfoView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
xmlns:vm="clr-namespace:Serein.Workbench.ViewModels"
|
||||||
|
xmlns:converter="clr-namespace:Serein.Workbench.Converters"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="600" d:DesignWidth="300"
|
||||||
|
d:DataContext="{d:DesignInstance vm:CanvasInfoViewModel}">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter"/>
|
||||||
|
<Style x:Key="InfoTipsTextBlock" TargetType="TextBlock">
|
||||||
|
<Setter Property="Width" Value="70"/>
|
||||||
|
<Setter Property="MinWidth" Value="70"/>
|
||||||
|
<Setter Property="MaxHeight" Value="70"/>
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
|
</Style>
|
||||||
|
<Style x:Key="InfoValueTextBox" TargetType="TextBox">
|
||||||
|
<Setter Property="Width" Value="170"/>
|
||||||
|
<Setter Property="MinWidth" Value="170"/>
|
||||||
|
<Setter Property="MaxHeight" Value="170"/>
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
|
</Style>
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Margin="10" >
|
||||||
|
<TextBlock Text="公开节点" HorizontalAlignment="Left"/>
|
||||||
|
<ListBox ItemsSource="{Binding Model.PublicNodes}"
|
||||||
|
Visibility="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource CountToVisibilityConverter}}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding DisplayName}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
|
||||||
|
</ListBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Margin="10">
|
||||||
|
<TextBlock Text="流程节点" HorizontalAlignment="Left"/>
|
||||||
|
<ListBox ItemsSource="{Binding Model.Nodes}"
|
||||||
|
Visibility="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource CountToVisibilityConverter}}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding DisplayName}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Margin="10">
|
||||||
|
<TextBlock Text="画布信息" HorizontalAlignment="Left"/>
|
||||||
|
<!--<StackPanel Margin="2" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="GUID" Style="{StaticResource InfoTipsTextBlock}" />
|
||||||
|
<TextBox Text="{Binding Model.Guid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource InfoValueTextBox}"/>
|
||||||
|
</StackPanel>-->
|
||||||
|
<StackPanel Margin="1" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="画布名称" Style="{StaticResource InfoTipsTextBlock}" />
|
||||||
|
<TextBox Text="{Binding Model.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource InfoValueTextBox}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="1" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="尺寸宽度" Style="{StaticResource InfoTipsTextBlock}" />
|
||||||
|
<TextBox Text="{Binding Model.Width, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource InfoValueTextBox}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="1" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="尺寸高度" Style="{StaticResource InfoTipsTextBlock}" />
|
||||||
|
<TextBox Text="{Binding Model.Height, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource InfoValueTextBox}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="1" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="预览位置X" Style="{StaticResource InfoTipsTextBlock}" />
|
||||||
|
<TextBox Text="{Binding Model.ViewX, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource InfoValueTextBox}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="1" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="预览位置Y" Style="{StaticResource InfoTipsTextBlock}" />
|
||||||
|
<TextBox Text="{Binding Model.ViewY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource InfoValueTextBox}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
32
Workbench/Views/CanvasInfoView.xaml.cs
Normal file
32
Workbench/Views/CanvasInfoView.xaml.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Serein.Workbench.ViewModels;
|
||||||
|
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.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace Serein.Workbench.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CanvasNodeTreeView.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class CanvasInfoView : UserControl
|
||||||
|
{
|
||||||
|
private readonly CanvasInfoViewModel ViewModel;
|
||||||
|
public CanvasInfoView()
|
||||||
|
{
|
||||||
|
this.ViewModel = App.GetService<CanvasInfoViewModel>();
|
||||||
|
this.DataContext = this.ViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -374,14 +374,14 @@ namespace Serein.Workbench.Views
|
|||||||
// 准备放置条件表达式控件
|
// 准备放置条件表达式控件
|
||||||
if (nodeControl.ViewModel.NodeModel.ControlType == NodeControlType.ExpCondition)
|
if (nodeControl.ViewModel.NodeModel.ControlType == NodeControlType.ExpCondition)
|
||||||
{
|
{
|
||||||
ConditionRegionControl? conditionRegion = WpfFuncTool.GetParentOfType<ConditionRegionControl>(hitElement);
|
/* ConditionRegionControl? conditionRegion = WpfFuncTool.GetParentOfType<ConditionRegionControl>(hitElement);
|
||||||
if (conditionRegion is not null)
|
if (conditionRegion is not null)
|
||||||
{
|
{
|
||||||
targetNodeControl = conditionRegion;
|
targetNodeControl = conditionRegion;
|
||||||
//// 如果存在条件区域容器
|
//// 如果存在条件区域容器
|
||||||
//conditionRegion.AddCondition(nodeControl);
|
//conditionRegion.AddCondition(nodeControl);
|
||||||
return true;
|
return true;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -408,13 +408,24 @@ namespace Serein.Workbench.Views
|
|||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
private void KeyEventService_OnKeyDown(Key key)
|
private void KeyEventService_OnKeyDown(Key key)
|
||||||
{
|
{
|
||||||
if (!flowNodeService.CurrentSelectCanvas.Guid.Equals(Guid))
|
|
||||||
|
if (flowNodeService.CurrentSelectCanvas is null || !flowNodeService.CurrentSelectCanvas.Guid.Equals(Guid))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (key == Key.F5)
|
||||||
|
{
|
||||||
|
// F5 调试当前流程
|
||||||
|
_ = flowEnvironment.StartFlowAsync([Guid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (key == Key.Escape)
|
if (key == Key.Escape)
|
||||||
{
|
{
|
||||||
|
// 退出连线、选取状态
|
||||||
IsControlDragging = false;
|
IsControlDragging = false;
|
||||||
IsCanvasDragging = false;
|
IsCanvasDragging = false;
|
||||||
SelectionRectangle.Visibility = Visibility.Collapsed;
|
SelectionRectangle.Visibility = Visibility.Collapsed;
|
||||||
@@ -427,16 +438,33 @@ namespace Serein.Workbench.Views
|
|||||||
if (selectNodeControls.Count > 0 && key == Key.C && (keyEventService.GetKeyState(Key.LeftCtrl) || keyEventService.GetKeyState(Key.RightCtrl)))
|
if (selectNodeControls.Count > 0 && key == Key.C && (keyEventService.GetKeyState(Key.LeftCtrl) || keyEventService.GetKeyState(Key.RightCtrl)))
|
||||||
{
|
{
|
||||||
var text = flowNodeService.CpoyNodeInfo([.. selectNodeControls.Select(c => c.ViewModel.NodeModel)]);
|
var text = flowNodeService.CpoyNodeInfo([.. selectNodeControls.Select(c => c.ViewModel.NodeModel)]);
|
||||||
Clipboard.SetDataObject(text, true); // 复制,持久性设置
|
//Clipboard.SetText(text); // 复制,持久性设置
|
||||||
return;
|
try
|
||||||
|
{
|
||||||
|
Clipboard.SetDataObject(text, true); // 复制,持久性设置
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Clipboard.SetText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 粘贴节点
|
// 粘贴节点
|
||||||
if (key == Key.V && (keyEventService.GetKeyState(Key.LeftCtrl) || keyEventService.GetKeyState(Key.RightCtrl)))
|
if (key == Key.V && (keyEventService.GetKeyState(Key.LeftCtrl) || keyEventService.GetKeyState(Key.RightCtrl)))
|
||||||
{
|
{
|
||||||
string clipboardText = Clipboard.GetText(TextDataFormat.Text); // 获取复制的文本
|
string clipboardText = Clipboard.GetText(TextDataFormat.Text); // 获取复制的文本
|
||||||
var jobject = JObject.Parse(clipboardText);
|
string nodesText = "";
|
||||||
var nodesText = jobject["nodes"]?.ToString();
|
try
|
||||||
|
{
|
||||||
|
var jobject = JObject.Parse(clipboardText);
|
||||||
|
nodesText = jobject["nodes"]?.ToString();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(nodesText))
|
if (!string.IsNullOrWhiteSpace(nodesText))
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -596,7 +624,7 @@ namespace Serein.Workbench.Views
|
|||||||
{
|
{
|
||||||
NodeControlType nodeControlType = droppedType switch
|
NodeControlType nodeControlType = droppedType switch
|
||||||
{
|
{
|
||||||
Type when typeof(ConditionRegionControl).IsAssignableFrom(droppedType) => NodeControlType.ConditionRegion, // 条件区域
|
//Type when typeof(ConditionRegionControl).IsAssignableFrom(droppedType) => NodeControlType.ConditionRegion, // 条件区域
|
||||||
Type when typeof(ConditionNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpCondition,
|
Type when typeof(ConditionNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpCondition,
|
||||||
Type when typeof(ExpOpNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpOp,
|
Type when typeof(ExpOpNodeControl).IsAssignableFrom(droppedType) => NodeControlType.ExpOp,
|
||||||
Type when typeof(GlobalDataControl).IsAssignableFrom(droppedType) => NodeControlType.GlobalData,
|
Type when typeof(GlobalDataControl).IsAssignableFrom(droppedType) => NodeControlType.GlobalData,
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
xmlns:local="clr-namespace:Serein.Workbench.Views"
|
||||||
|
xmlns:converters="clr-namespace:Serein.Workbench.Tool.Converters"
|
||||||
xmlns:vm="clr-namespace:Serein.Workbench.ViewModels"
|
xmlns:vm="clr-namespace:Serein.Workbench.ViewModels"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
d:DataContext="{d:DesignInstance vm:FlowEditViewModel}"
|
d:DataContext="{d:DesignInstance vm:FlowEditViewModel}"
|
||||||
xmlns:converters="clr-namespace:Serein.Workbench.Tool.Converters"
|
|
||||||
Background="#E7F0F6">
|
Background="#E7F0F6">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<converters:InvertableBooleanToVisibilityConverter x:Key="InvertableBooleanToVisibilityConverter"/>
|
<converters:InvertableBooleanToVisibilityConverter x:Key="InvertableBooleanToVisibilityConverter"/>
|
||||||
@@ -17,19 +17,20 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
|
|
||||||
<TabControl SelectedItem="{Binding SelectedTab}"
|
<TabControl SelectedItem="{Binding SelectedTab}"
|
||||||
|
ItemsSource="{Binding CanvasTabs}"
|
||||||
SelectionChanged="TabControl_SelectionChanged"
|
SelectionChanged="TabControl_SelectionChanged"
|
||||||
x:Name="CanvasTab">
|
x:Name="CanvasTab">
|
||||||
<TabControl.ItemTemplate>
|
<TabControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<StackPanel >
|
<StackPanel >
|
||||||
<!-- 双击选项卡名称来进入编辑模式 -->
|
<!-- 双击选项卡名称来进入编辑模式 -->
|
||||||
<TextBlock Text="{Binding Name}"
|
<TextBlock Text="{Binding Model.Name}"
|
||||||
FontSize="18"
|
FontSize="18"
|
||||||
Visibility="{Binding IsEditing, Converter={StaticResource InvertableBooleanToVisibilityConverter},ConverterParameter=Inverted}"
|
Visibility="{Binding IsEditing, Converter={StaticResource InvertableBooleanToVisibilityConverter},ConverterParameter=Inverted}"
|
||||||
PreviewMouseLeftButtonDown="TextBlock_PreviewMouseLeftButtonDown"
|
PreviewMouseLeftButtonDown="TextBlock_PreviewMouseLeftButtonDown"
|
||||||
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
|
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
|
||||||
<!-- 编辑模式下显示TextBox -->
|
<!-- 编辑模式下显示TextBox -->
|
||||||
<TextBox Text="{Binding Name, Mode=TwoWay}"
|
<TextBox Text="{Binding Model.Name, Mode=TwoWay}"
|
||||||
FontSize="18"
|
FontSize="18"
|
||||||
Visibility="{Binding IsEditing, Converter={StaticResource InvertableBooleanToVisibilityConverter},ConverterParameter=Normal}"
|
Visibility="{Binding IsEditing, Converter={StaticResource InvertableBooleanToVisibilityConverter},ConverterParameter=Normal}"
|
||||||
KeyDown="TextBox_KeyDown" />
|
KeyDown="TextBox_KeyDown" />
|
||||||
@@ -37,10 +38,7 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</TabControl.ItemTemplate>
|
</TabControl.ItemTemplate>
|
||||||
|
|
||||||
<!-- Tabs Collection -->
|
|
||||||
<TabControl.ItemsSource>
|
|
||||||
<Binding Path="CanvasTabs" />
|
|
||||||
</TabControl.ItemsSource>
|
|
||||||
|
|
||||||
<!-- Content of the Tab (e.g., FlowCanvasView) -->
|
<!-- Content of the Tab (e.g., FlowCanvasView) -->
|
||||||
<TabControl.ContentTemplate>
|
<TabControl.ContentTemplate>
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
<!--流程编辑区-->
|
<!--流程编辑区-->
|
||||||
<local:FlowEditView Grid.Row="1" Grid.Column="2"/>
|
<local:FlowEditView Grid.Row="1" Grid.Column="2"/>
|
||||||
<!--编辑区和视图区的分割线-->
|
<!--编辑区和视图区的分割线-->
|
||||||
<GridSplitter Grid.Row="1" Grid.Column="3" Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="#CCD5F0" />
|
<GridSplitter Grid.Row="1" Grid.Column="3" Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="#CCD5F0" />
|
||||||
|
|
||||||
|
<local:CanvasInfoView Grid.Row="1" Grid.Column="4" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
Reference in New Issue
Block a user