mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-14 20:06:34 +08:00
重新确认开发方向
This commit is contained in:
@@ -390,7 +390,10 @@ namespace Serein.Library.Api
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否全局中断
|
/// 是否全局中断
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsGlobalInterrupt { get; }
|
bool IsGlobalInterrupt { get; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 事件
|
#region 事件
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Serein.Library.Entity
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 节点入参参数信息
|
|
||||||
/// </summary>
|
|
||||||
public class ExplicitData
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 参数索引
|
|
||||||
/// </summary>
|
|
||||||
public int Index { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 是否为显式参数(固定值/表达式)
|
|
||||||
/// </summary>
|
|
||||||
public bool IsExplicitData { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 转换器 IEnumConvertor<,>
|
|
||||||
/// </summary>
|
|
||||||
public Func<object, object> Convertor { get; set; }
|
|
||||||
///// <summary>
|
|
||||||
///// 显式类型
|
|
||||||
///// </summary>
|
|
||||||
public Type ExplicitType { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// 显示类型编号>
|
|
||||||
///// </summary>
|
|
||||||
public string ExplicitTypeName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 方法需要的类型
|
|
||||||
/// </summary>
|
|
||||||
public Type DataType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 方法入参参数名称
|
|
||||||
/// </summary>
|
|
||||||
public string ParameterName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 入参值(在UI上输入的文本内容)
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public string DataValue { get; set; }
|
|
||||||
|
|
||||||
public object[] Items { get; set; }
|
|
||||||
|
|
||||||
public ExplicitData Clone() => new ExplicitData()
|
|
||||||
{
|
|
||||||
Index = Index,
|
|
||||||
IsExplicitData = IsExplicitData,
|
|
||||||
ExplicitType = ExplicitType,
|
|
||||||
ExplicitTypeName = ExplicitTypeName,
|
|
||||||
Convertor = Convertor,
|
|
||||||
DataType = DataType,
|
|
||||||
ParameterName = ParameterName,
|
|
||||||
DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue,
|
|
||||||
Items = Items.Select(it => it).ToArray(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,44 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Serein.Library.Entity
|
namespace Serein.Library.Entity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 方法描述信息
|
||||||
|
/// </summary>
|
||||||
|
public class MethodDetailsInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属于哪个DLL文件
|
||||||
|
/// </summary>
|
||||||
|
public string LibraryName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法名称
|
||||||
|
/// </summary>
|
||||||
|
public string MethodName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点类型
|
||||||
|
/// </summary>
|
||||||
|
public string NodeType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法说明
|
||||||
|
/// </summary>
|
||||||
|
public string MethodTips { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数内容
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public ParameterDetailsInfo[] ParameterDetailsInfos { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出参类型
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public string ReturnTypeFullName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -12,6 +50,24 @@ namespace Serein.Library.Entity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MethodDetails
|
public class MethodDetails
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 转为信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public MethodDetailsInfo ToInfo()
|
||||||
|
{
|
||||||
|
return new MethodDetailsInfo
|
||||||
|
{
|
||||||
|
MethodName = MethodName,
|
||||||
|
MethodTips = MethodTips,
|
||||||
|
NodeType = MethodDynamicType.ToString(),
|
||||||
|
ParameterDetailsInfos = this.ParameterDetailss.Select(p => p.ToInfo()).ToArray(),
|
||||||
|
ReturnTypeFullName = ReturnType.FullName,
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从DLL拖动出来时拷贝新的实例
|
/// 从DLL拖动出来时拷贝新的实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -28,7 +84,7 @@ namespace Serein.Library.Entity
|
|||||||
MethodName = MethodName,
|
MethodName = MethodName,
|
||||||
MethodLockName = MethodLockName,
|
MethodLockName = MethodLockName,
|
||||||
IsProtectionParameter = IsProtectionParameter,
|
IsProtectionParameter = IsProtectionParameter,
|
||||||
ExplicitDatas = ExplicitDatas?.Select(it => it.Clone()).ToArray(),
|
ParameterDetailss = ParameterDetailss?.Select(it => it.Clone()).ToArray(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,10 +126,10 @@ namespace Serein.Library.Entity
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 参数内容
|
/// 参数描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public ExplicitData[] ExplicitDatas { get; set; }
|
public ParameterDetails[] ParameterDetailss { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 出参类型
|
/// 出参类型
|
||||||
|
|||||||
116
Library/Entity/ParameterDetails.cs
Normal file
116
Library/Entity/ParameterDetails.cs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Serein.Library.Entity
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法入参描述
|
||||||
|
/// </summary>
|
||||||
|
public class ParameterDetailsInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 参数索引
|
||||||
|
/// </summary>
|
||||||
|
public int Index { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法需要的类型
|
||||||
|
/// </summary>
|
||||||
|
public string DataTypeFullName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法入参参数名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 节点入参参数详情
|
||||||
|
/// </summary>
|
||||||
|
public class ParameterDetails
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 转为描述
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public ParameterDetailsInfo ToInfo()
|
||||||
|
{
|
||||||
|
return new ParameterDetailsInfo
|
||||||
|
{
|
||||||
|
Index = Index,
|
||||||
|
DataTypeFullName = DataType.FullName,
|
||||||
|
Name = Name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝新的对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public ParameterDetails Clone() => new ParameterDetails()
|
||||||
|
{
|
||||||
|
Index = Index,
|
||||||
|
IsExplicitData = IsExplicitData,
|
||||||
|
ExplicitType = ExplicitType,
|
||||||
|
ExplicitTypeName = ExplicitTypeName,
|
||||||
|
Convertor = Convertor,
|
||||||
|
DataType = DataType,
|
||||||
|
Name = Name,
|
||||||
|
DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue,
|
||||||
|
Items = Items.Select(it => it).ToArray(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数索引
|
||||||
|
/// </summary>
|
||||||
|
public int Index { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为显式参数(固定值/表达式)
|
||||||
|
/// </summary>
|
||||||
|
public bool IsExplicitData { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 转换器 IEnumConvertor<,>
|
||||||
|
/// </summary>
|
||||||
|
public Func<object, object> Convertor { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 显式类型
|
||||||
|
/// </summary>
|
||||||
|
public Type ExplicitType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目前存在三种状态:Select/Bool/Value
|
||||||
|
/// <para>Select : 枚举值</para>
|
||||||
|
/// <para>Bool : 布尔类型</para>
|
||||||
|
/// <para>Value : 除以上类型之外的任意参数</para>
|
||||||
|
/// </summary>
|
||||||
|
public string ExplicitTypeName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法需要的类型
|
||||||
|
/// </summary>
|
||||||
|
public Type DataType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法入参参数名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 入参值(在UI上输入的文本内容)
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public string DataValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 如果是引用类型,拷贝时不会发生改变。
|
||||||
|
/// </summary>
|
||||||
|
public object[] Items { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -39,7 +39,6 @@ namespace Serein.Library.Entity
|
|||||||
|
|
||||||
public NodeInfo[] Nodes { get; set; }
|
public NodeInfo[] Nodes { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ namespace Serein.NodeFlow.Base
|
|||||||
for (int i = 0; i < nodeInfo.ParameterData.Length; i++)
|
for (int i = 0; i < nodeInfo.ParameterData.Length; i++)
|
||||||
{
|
{
|
||||||
Parameterdata? pd = nodeInfo.ParameterData[i];
|
Parameterdata? pd = nodeInfo.ParameterData[i];
|
||||||
this.MethodDetails.ExplicitDatas[i].IsExplicitData = pd.State;
|
this.MethodDetails.ParameterDetailss[i].IsExplicitData = pd.State;
|
||||||
this.MethodDetails.ExplicitDatas[i].DataValue = pd.Value;
|
this.MethodDetails.ParameterDetailss[i].DataValue = pd.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,12 +232,12 @@ namespace Serein.NodeFlow.Base
|
|||||||
public static object?[]? GetParameters(IDynamicContext context, NodeModelBase nodeModel, MethodDetails md)
|
public static object?[]? GetParameters(IDynamicContext context, NodeModelBase nodeModel, MethodDetails md)
|
||||||
{
|
{
|
||||||
// 用正确的大小初始化参数数组
|
// 用正确的大小初始化参数数组
|
||||||
if (md.ExplicitDatas.Length == 0)
|
if (md.ParameterDetailss.Length == 0)
|
||||||
{
|
{
|
||||||
return null;// md.ActingInstance
|
return null;// md.ActingInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
object?[]? parameters = new object[md.ExplicitDatas.Length];
|
object?[]? parameters = new object[md.ParameterDetailss.Length];
|
||||||
var flowData = nodeModel.PreviousNode?.FlowData; // 当前传递的数据
|
var flowData = nodeModel.PreviousNode?.FlowData; // 当前传递的数据
|
||||||
var previousDataType = flowData?.GetType();
|
var previousDataType = flowData?.GetType();
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ namespace Serein.NodeFlow.Base
|
|||||||
{
|
{
|
||||||
|
|
||||||
object? inputParameter; // 存放解析的临时参数
|
object? inputParameter; // 存放解析的临时参数
|
||||||
var ed = md.ExplicitDatas[i]; // 方法入参描述
|
var ed = md.ParameterDetailss[i]; // 方法入参描述
|
||||||
|
|
||||||
|
|
||||||
if (ed.IsExplicitData) // 判断是否使用显示的输入参数
|
if (ed.IsExplicitData) // 判断是否使用显示的输入参数
|
||||||
|
|||||||
@@ -36,7 +36,26 @@ namespace Serein.NodeFlow
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
public List<library> get(){
|
||||||
|
}
|
||||||
|
|
||||||
|
libray
|
||||||
|
{
|
||||||
|
string dllname,
|
||||||
|
MethodInfo[] nodeinfos
|
||||||
|
}
|
||||||
|
|
||||||
|
methodInfo{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 运行环境
|
/// 运行环境
|
||||||
@@ -58,8 +77,6 @@ namespace Serein.NodeFlow
|
|||||||
sereinIOC.OnIOCMembersChanged += e => this?.OnIOCMembersChanged?.Invoke(e) ; // 监听IOC容器的注册
|
sereinIOC.OnIOCMembersChanged += e => this?.OnIOCMembersChanged?.Invoke(e) ; // 监听IOC容器的注册
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点的命名空间
|
/// 节点的命名空间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -169,9 +186,8 @@ namespace Serein.NodeFlow
|
|||||||
public List<NodeLibrary> NodeLibrarys { get; } = [];
|
public List<NodeLibrary> NodeLibrarys { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 存储所有方法信息
|
/// 描述所有DLL中NodeAction特性的方法的原始副本
|
||||||
/// </summary>
|
/// </summary>
|
||||||
//private MethodDetailss { get; } = [];
|
|
||||||
public Dictionary<NodeLibrary, List<MethodDetails>> MethodDetailss { get; } = [];
|
public Dictionary<NodeLibrary, List<MethodDetails>> MethodDetailss { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -184,6 +200,10 @@ namespace Serein.NodeFlow
|
|||||||
/// 存放触发器节点(运行时全部调用)
|
/// 存放触发器节点(运行时全部调用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
public List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从dll中加载的类的注册类型
|
||||||
|
/// </summary>
|
||||||
public Dictionary<RegisterSequence,List<Type>> AutoRegisterTypes { get; } = [];
|
public Dictionary<RegisterSequence,List<Type>> AutoRegisterTypes { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -336,16 +356,18 @@ namespace Serein.NodeFlow
|
|||||||
var dllPaths = project.Librarys.Select(it => it.Path).ToList();
|
var dllPaths = project.Librarys.Select(it => it.Path).ToList();
|
||||||
List<MethodDetails> methodDetailss = [];
|
List<MethodDetails> methodDetailss = [];
|
||||||
|
|
||||||
|
//string currentPath = Environment.CurrentDirectory; // 获取当前目录
|
||||||
|
//string path = Assembly.GetExecutingAssembly().Location; // 获取当前正在执行的文件的路径
|
||||||
|
//string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // 获取包含可执行文件的目录
|
||||||
|
//string basePath = AppDomain.CurrentDomain.BaseDirectory; // 获取应用程序的执行路径:
|
||||||
|
|
||||||
// 遍历依赖项中的特性注解,生成方法详情
|
// 遍历依赖项中的特性注解,生成方法详情
|
||||||
foreach (var dll in dllPaths)
|
foreach (var dllPath in dllPaths)
|
||||||
{
|
{
|
||||||
var dllFilePath = System.IO.Path.GetFullPath(System.IO.Path.Combine(filePath, dll));
|
var dllFilePath = Path.GetFullPath(Path.Combine(filePath, dllPath));
|
||||||
|
//var dllFilePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(filePath)!, dllPath));
|
||||||
LoadDllNodeInfo(dllFilePath);
|
LoadDllNodeInfo(dllFilePath);
|
||||||
}
|
}
|
||||||
// 方法加载完成,缓存到运行环境中。
|
|
||||||
//MethodDetailss.AddRange(methodDetailss);
|
|
||||||
//methodDetailss.Clear();
|
|
||||||
|
|
||||||
|
|
||||||
List<(NodeModelBase, string[])> regionChildNodes = new List<(NodeModelBase, string[])>();
|
List<(NodeModelBase, string[])> regionChildNodes = new List<(NodeModelBase, string[])>();
|
||||||
List<(NodeModelBase, Position)> ordinaryNodes = new List<(NodeModelBase, Position)>();
|
List<(NodeModelBase, Position)> ordinaryNodes = new List<(NodeModelBase, Position)>();
|
||||||
@@ -1325,10 +1347,11 @@ namespace Serein.NodeFlow
|
|||||||
{
|
{
|
||||||
public static Library.Entity.Library ToLibrary(this Assembly assembly)
|
public static Library.Entity.Library ToLibrary(this Assembly assembly)
|
||||||
{
|
{
|
||||||
|
var tmp = assembly.ManifestModule.Name;
|
||||||
return new Library.Entity.Library
|
return new Library.Entity.Library
|
||||||
{
|
{
|
||||||
Name = assembly.GetName().Name,
|
Name = assembly.GetName().Name,
|
||||||
Path = assembly.Location,
|
Path = assembly.ManifestModule.Name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace Serein.NodeFlow.Model
|
|||||||
|
|
||||||
internal override Parameterdata[] GetParameterdatas()
|
internal override Parameterdata[] GetParameterdatas()
|
||||||
{
|
{
|
||||||
if (base.MethodDetails.ExplicitDatas.Length > 0)
|
if (base.MethodDetails.ParameterDetailss.Length > 0)
|
||||||
{
|
{
|
||||||
return MethodDetails.ExplicitDatas
|
return MethodDetails.ParameterDetailss
|
||||||
.Select(it => new Parameterdata
|
.Select(it => new Parameterdata
|
||||||
{
|
{
|
||||||
State = it.IsExplicitData,
|
State = it.IsExplicitData,
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ namespace Serein.NodeFlow.Model
|
|||||||
}
|
}
|
||||||
internal override Parameterdata[] GetParameterdatas()
|
internal override Parameterdata[] GetParameterdatas()
|
||||||
{
|
{
|
||||||
if (base.MethodDetails.ExplicitDatas.Length > 0)
|
if (base.MethodDetails.ParameterDetailss.Length > 0)
|
||||||
{
|
{
|
||||||
return MethodDetails.ExplicitDatas
|
return MethodDetails.ParameterDetailss
|
||||||
.Select(it => new Parameterdata
|
.Select(it => new Parameterdata
|
||||||
{
|
{
|
||||||
State = it.IsExplicitData,
|
State = it.IsExplicitData,
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
MethodDynamicType = attribute.MethodDynamicType,
|
MethodDynamicType = attribute.MethodDynamicType,
|
||||||
MethodLockName = attribute.LockName,
|
MethodLockName = attribute.LockName,
|
||||||
MethodTips = methodTips,
|
MethodTips = methodTips,
|
||||||
ExplicitDatas = explicitDataOfParameters,
|
ParameterDetailss = explicitDataOfParameters,
|
||||||
ReturnType = returnType,
|
ReturnType = returnType,
|
||||||
};
|
};
|
||||||
var dd = new DelegateDetails( emitMethodType, methodDelegate) ;
|
var dd = new DelegateDetails( emitMethodType, methodDelegate) ;
|
||||||
@@ -173,7 +173,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static ExplicitData[] GetExplicitDataOfParameters(ParameterInfo[] parameters)
|
private static ParameterDetails[] GetExplicitDataOfParameters(ParameterInfo[] parameters)
|
||||||
{
|
{
|
||||||
|
|
||||||
return parameters.Select((it, index) =>
|
return parameters.Select((it, index) =>
|
||||||
@@ -212,7 +212,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
return methodInfo?.Invoke(obj, [enumValue]);
|
return methodInfo?.Invoke(obj, [enumValue]);
|
||||||
};
|
};
|
||||||
// 确保实例实现了所需接口
|
// 确保实例实现了所需接口
|
||||||
ExplicitData ed = GetExplicitDataOfParameter(it, index, paremType, true, func);
|
ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true, func);
|
||||||
|
|
||||||
return ed;
|
return ed;
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
}).ToArray();
|
}).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ExplicitData GetExplicitDataOfParameter(ParameterInfo parameterInfo,
|
private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo,
|
||||||
int index,
|
int index,
|
||||||
Type paremType,
|
Type paremType,
|
||||||
bool isExplicitData,
|
bool isExplicitData,
|
||||||
@@ -247,7 +247,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
string explicitTypeName = GetExplicitTypeName(paremType);
|
string explicitTypeName = GetExplicitTypeName(paremType);
|
||||||
var items = GetExplicitItems(paremType, explicitTypeName);
|
var items = GetExplicitItems(paremType, explicitTypeName);
|
||||||
if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
|
if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
|
||||||
return new ExplicitData
|
return new ParameterDetails
|
||||||
{
|
{
|
||||||
IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true,
|
IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true,
|
||||||
Index = index,
|
Index = index,
|
||||||
@@ -255,9 +255,9 @@ public static class NodeMethodDetailsHelper
|
|||||||
ExplicitType = paremType,
|
ExplicitType = paremType,
|
||||||
Convertor = func,
|
Convertor = func,
|
||||||
DataType = parameterInfo.ParameterType,
|
DataType = parameterInfo.ParameterType,
|
||||||
ParameterName = parameterInfo.Name,
|
Name = parameterInfo.Name,
|
||||||
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "",
|
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
|
||||||
Items = items.ToArray(),
|
Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
不定期在Bilibili个人空间上更新相关的视频。
|
不定期在Bilibili个人空间上更新相关的视频。
|
||||||
https://space.bilibili.com/33526379
|
https://space.bilibili.com/33526379
|
||||||
|
|
||||||
# 计划任务 2024年9月17日更新
|
# 计划任务 2024年10月13日更新
|
||||||
* (重要+优先)正在实现单步执行
|
* (优先)正在开发远程管理插件与远程操作客户端
|
||||||
|
* 计划实现不停机更新类库(更新整个DLL/某个节点),但似乎难度过大
|
||||||
|
* 计划实现单步执行
|
||||||
* 计划实现节点树视图、IOC容器对象视图
|
* 计划实现节点树视图、IOC容器对象视图
|
||||||
* 正在计划新增基础节点“属性包装器”,用来收集各个节点的数据,包装成匿名对象/Json类型(暂时未想到如何设计)
|
* 计划新增基础节点“属性包装器”,用来收集各个节点的数据,包装成匿名对象/Json类型(暂时未想到如何设计)
|
||||||
|
|
||||||
|
|
||||||
# 如何加载我的DLL?
|
# 如何加载我的DLL?
|
||||||
|
|||||||
@@ -11,16 +11,10 @@ using Serein.Library.Core.NodeFlow;
|
|||||||
using Serein.Library.NodeFlow.Tool;
|
using Serein.Library.NodeFlow.Tool;
|
||||||
using Serein.Library.Utils;
|
using Serein.Library.Utils;
|
||||||
using Serein.FlowRemoteManagement.Model;
|
using Serein.FlowRemoteManagement.Model;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace SereinFlowRemoteManagement
|
namespace SereinFlowRemoteManagement
|
||||||
{
|
{
|
||||||
public enum FlowEnvCommand
|
|
||||||
{
|
|
||||||
A,
|
|
||||||
B,
|
|
||||||
C,
|
|
||||||
D
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -29,12 +23,12 @@ namespace SereinFlowRemoteManagement
|
|||||||
[DynamicFlow]
|
[DynamicFlow]
|
||||||
[AutoRegister]
|
[AutoRegister]
|
||||||
[AutoSocketModule(ThemeKey ="theme",DataKey ="data")]
|
[AutoSocketModule(ThemeKey ="theme",DataKey ="data")]
|
||||||
public class FlowRemoteManagement : FlowTrigger<FlowEnvCommand>, ISocketHandleModule
|
public class FlowRemoteManagement : ISocketHandleModule
|
||||||
{
|
{
|
||||||
#region 初始化
|
#region 初始化
|
||||||
public Guid HandleGuid { get; } = new Guid();
|
public Guid HandleGuid { get; } = new Guid();
|
||||||
|
|
||||||
private readonly FlowEnvironment environment;
|
private readonly FlowEnvironment environment;
|
||||||
public FlowRemoteManagement(IFlowEnvironment environment)
|
public FlowRemoteManagement(IFlowEnvironment environment)
|
||||||
{
|
{
|
||||||
if(environment is FlowEnvironment env)
|
if(environment is FlowEnvironment env)
|
||||||
@@ -67,6 +61,7 @@ namespace SereinFlowRemoteManagement
|
|||||||
ex = ex.Message
|
ex = ex.Message
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
await Console.Out.WriteLineAsync("启动远程管理模块");
|
||||||
await socketServer.StartAsync("http://*:7525/");
|
await socketServer.StartAsync("http://*:7525/");
|
||||||
});
|
});
|
||||||
SereinProjectData projectData = environment.SaveProject();
|
SereinProjectData projectData = environment.SaveProject();
|
||||||
@@ -76,7 +71,7 @@ namespace SereinFlowRemoteManagement
|
|||||||
#region 对外接口
|
#region 对外接口
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更改两个节点的连接关系
|
/// 远程更改两个节点的连接关系
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodeInfo"></param>
|
/// <param name="nodeInfo"></param>
|
||||||
/// <param name="Send"></param>
|
/// <param name="Send"></param>
|
||||||
@@ -107,36 +102,20 @@ namespace SereinFlowRemoteManagement
|
|||||||
/// 远程调用某个节点
|
/// 远程调用某个节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AutoSocketHandle(ThemeValue = "InvokeNode")]
|
[AutoSocketHandle(ThemeValue = "InvokeNode")]
|
||||||
public async Task InvokeNode(bool isBranchEx, string nodeGuid, Func<object, Task> Send)
|
public async Task InvokeNode(string nodeGuid, Func<object, Task> Send)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(nodeGuid))
|
if (string.IsNullOrEmpty(nodeGuid))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Guid错误");
|
throw new InvalidOperationException("Guid错误");
|
||||||
}
|
}
|
||||||
if(!environment.Nodes.TryGetValue(nodeGuid, out var nodeModel) )
|
|
||||||
|
await environment.StartFlowInSelectNodeAsync(nodeGuid);
|
||||||
|
|
||||||
|
await Send(new
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("不存在这样的节点");
|
state = 200,
|
||||||
}
|
tips = "执行完成",
|
||||||
IDynamicContext dynamicContext = new DynamicContext(environment);
|
});
|
||||||
object? result = null;
|
|
||||||
if(isBranchEx)
|
|
||||||
{
|
|
||||||
await nodeModel.StartFlowAsync(dynamicContext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = await nodeModel.ExecutingAsync(dynamicContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result is not Task)
|
|
||||||
{
|
|
||||||
await Send(new
|
|
||||||
{
|
|
||||||
state = 200,
|
|
||||||
tips = "执行完成",
|
|
||||||
data = result
|
|
||||||
}) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -150,37 +129,49 @@ namespace SereinFlowRemoteManagement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到运行环境,获取当前的节点信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Send"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[AutoSocketHandle]
|
||||||
|
public async Task<object?> ConnectWorkBench(Func<string, Task> Send)
|
||||||
|
{
|
||||||
|
await Send("尝试获取");
|
||||||
|
|
||||||
|
Dictionary<NodeLibrary, List<MethodDetailsInfo>> LibraryMds = [];
|
||||||
|
|
||||||
|
foreach (var mdskv in environment.MethodDetailss)
|
||||||
|
{
|
||||||
|
var library = mdskv.Key;
|
||||||
|
var mds = mdskv.Value;
|
||||||
|
foreach (var md in mds)
|
||||||
|
{
|
||||||
|
if(!LibraryMds.TryGetValue(library, out var t_mds))
|
||||||
|
{
|
||||||
|
t_mds = new List<MethodDetailsInfo>();
|
||||||
|
LibraryMds[library] = t_mds;
|
||||||
|
}
|
||||||
|
var mdInfo = md.ToInfo();
|
||||||
|
mdInfo.LibraryName = library.Assembly.GetName().FullName;
|
||||||
|
t_mds.Add(mdInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var project = await GetProjectInfo();
|
||||||
|
return new
|
||||||
|
{
|
||||||
|
project = project,
|
||||||
|
envNode = LibraryMds.Values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await Send(ex.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 测试节点
|
|
||||||
|
|
||||||
[NodeAction(NodeType.Flipflop, "触发器等待")]
|
|
||||||
public async Task<IFlipflopContext<object>> WaitFlipflop(FlowEnvCommand flowEnvCommand)
|
|
||||||
{
|
|
||||||
var result = await this.CreateTaskAsync<object>(flowEnvCommand);
|
|
||||||
return new FlipflopContext<object>(FlipflopStateType.Succeed, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NodeAction(NodeType.Action, "测试")]
|
|
||||||
public void Test()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello World");
|
|
||||||
}
|
|
||||||
|
|
||||||
[NodeAction(NodeType.Action, "等待")]
|
|
||||||
public async Task Wait(int wait = 5)
|
|
||||||
{
|
|
||||||
await Task.Delay(1000 * wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NodeAction(NodeType.Action, "输出")]
|
|
||||||
public void Console2(string value)
|
|
||||||
{
|
|
||||||
Console.WriteLine(value);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
|
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
using Serein.Library.Api;
|
using Serein.Library.Api;
|
||||||
using Serein.Library.Entity;
|
using Serein.Library.Entity;
|
||||||
using Serein.NodeFlow;
|
using Serein.NodeFlow;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Serein.FlowStartTool
|
namespace Serein.FlowStartTool
|
||||||
{
|
{
|
||||||
@@ -9,50 +11,66 @@ namespace Serein.FlowStartTool
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Hello~");
|
Console.WriteLine("Hello :) ");
|
||||||
// 检查是否传入了参数
|
Console.WriteLine($"args : {string.Join(" , ", args)}");
|
||||||
if (args.Length == 1)
|
string filePath;
|
||||||
|
string fileDataPath;
|
||||||
|
SereinProjectData? flowProjectData;
|
||||||
|
|
||||||
|
string exeAssemblyDictPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
|
||||||
|
if (args.Length == 1)
|
||||||
|
{
|
||||||
|
filePath = args[0];
|
||||||
|
fileDataPath = Path.GetDirectoryName(filePath) ?? "";
|
||||||
|
}
|
||||||
|
else if (args.Length == 0)
|
||||||
|
{
|
||||||
|
filePath = Process.GetCurrentProcess().ProcessName + ".dnf";
|
||||||
|
fileDataPath = exeAssemblyDictPath;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// 获取文件路径
|
|
||||||
string filePath = args[0];
|
|
||||||
// 检查文件是否存在
|
|
||||||
if (!File.Exists(filePath))
|
|
||||||
{
|
|
||||||
Console.WriteLine($"文件未找到:{filePath}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Console.WriteLine(filePath);
|
|
||||||
return;
|
return;
|
||||||
SereinProjectData? flowProjectData;
|
}
|
||||||
string fileDataPath;
|
|
||||||
try
|
Console.WriteLine($"Current Name : {filePath}");
|
||||||
|
Console.WriteLine($"Dict Path : {fileDataPath}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 读取文件内容
|
||||||
|
string content = File.ReadAllText(filePath); // 读取整个文件内容
|
||||||
|
flowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
||||||
|
if (flowProjectData is null || string.IsNullOrEmpty(fileDataPath))
|
||||||
{
|
{
|
||||||
// 读取文件内容
|
throw new Exception("项目文件读取异常");
|
||||||
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
|
|
||||||
flowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
|
||||||
fileDataPath = System.IO.Path.GetDirectoryName(filePath) ?? "";
|
|
||||||
if (flowProjectData is null || string.IsNullOrEmpty(fileDataPath))
|
|
||||||
{
|
|
||||||
throw new Exception("项目文件读取异常");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
}
|
||||||
{
|
catch (Exception ex)
|
||||||
Console.WriteLine($"读取文件时发生错误:{ex.Message}");
|
{
|
||||||
return;
|
Console.WriteLine($"读取文件时发生错误:{ex.Message}");
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
_ = StartFlow(flowProjectData, fileDataPath);
|
|
||||||
|
IsRuning = true;
|
||||||
|
StartFlow(flowProjectData, fileDataPath).GetAwaiter().GetResult();
|
||||||
|
while (IsRuning)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static IFlowEnvironment? Env;
|
public static IFlowEnvironment? Env;
|
||||||
|
public static bool IsRuning;
|
||||||
public static async Task StartFlow(SereinProjectData flowProjectData, string fileDataPath)
|
public static async Task StartFlow(SereinProjectData flowProjectData, string fileDataPath)
|
||||||
{
|
{
|
||||||
Env = new FlowEnvironment();
|
Env = new FlowEnvironment();
|
||||||
Env.LoadProject(flowProjectData, fileDataPath); // 加载项目
|
Env.LoadProject(flowProjectData, fileDataPath); // 加载项目
|
||||||
await Env.StartAsync();
|
await Env.StartAsync();
|
||||||
|
IsRuning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,16 @@
|
|||||||
<PublishSingleFile>true</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<AssemblyName>project</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0|AnyCPU'">
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0|AnyCPU'">
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -162,11 +162,12 @@ namespace Serein.WorkBench
|
|||||||
//filePath = @"F:\临时\project\tmp\project.dnf";
|
//filePath = @"F:\临时\project\tmp\project.dnf";
|
||||||
//filePath = @"D:\Project\C#\TestNetFramework\Net45DllTest\Net45DllTest\bin\Debug\project.dnf";
|
//filePath = @"D:\Project\C#\TestNetFramework\Net45DllTest\Net45DllTest\bin\Debug\project.dnf";
|
||||||
//filePath = @"D:\Project\C#\DynamicControl\SereinFlow\Net462DllTest\bin\Debug\project.dnf";
|
//filePath = @"D:\Project\C#\DynamicControl\SereinFlow\Net462DllTest\bin\Debug\project.dnf";
|
||||||
filePath = @"D:\Project\C#\DynamicControl\SereinFlow\.Output\Debug\net8.0-windows7.0\project.dnf";
|
//filePath = @"D:\Project\C#\DynamicControl\SereinFlow\.Output\Debug\net8.0-windows7.0\project.dnf";
|
||||||
|
filePath = @"F:\临时\project\linux\project.dnf";
|
||||||
//string filePath = @"D:\Project\C#\DynamicControl\SereinFlow\.Output\Debug\net8.0-windows7.0\U9 project.dnf";
|
//string filePath = @"D:\Project\C#\DynamicControl\SereinFlow\.Output\Debug\net8.0-windows7.0\U9 project.dnf";
|
||||||
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
|
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
|
||||||
App.FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
App.FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
||||||
App.FileDataPath = filePath;//System.IO.Path.GetDirectoryName(filePath)!;
|
App.FileDataPath =System.IO.Path.GetDirectoryName(filePath)!; // filePath;//
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -203,9 +203,6 @@ namespace Serein.WorkBench
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private LogWindow InitConsoleOut()
|
private LogWindow InitConsoleOut()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="{x:Type local:MethodDetailsControl}">
|
<ControlTemplate TargetType="{x:Type local:MethodDetailsControl}">
|
||||||
|
|
||||||
<ItemsControl ItemsSource="{Binding MethodDetails.ExplicitDatas, RelativeSource={RelativeSource TemplatedParent}}">
|
<ItemsControl ItemsSource="{Binding MethodDetails.ParameterDetailss, RelativeSource={RelativeSource TemplatedParent}}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<ContentControl Content="{Binding}">
|
<ContentControl Content="{Binding}">
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock Grid.Column="0" Text="{Binding Index,StringFormat=agr{0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="0" Text="{Binding Index,StringFormat=agr{0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center"/>
|
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center"/>
|
||||||
<TextBlock Grid.Column="2" MinWidth="50" Text="{Binding ParameterName}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="2" MinWidth="50" Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
<TextBlock Grid.Column="3" MinWidth="50" Text="无须指定参数"/>
|
<TextBlock Grid.Column="3" MinWidth="50" Text="无须指定参数"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock Grid.Column="0" Text="{Binding Index,StringFormat=agr{0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="0" Text="{Binding Index,StringFormat=agr{0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center"/>
|
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center"/>
|
||||||
<TextBlock Grid.Column="2" MinWidth="50" Text="{Binding ParameterName}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="2" MinWidth="50" Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
<ComboBox Grid.Column="3"
|
<ComboBox Grid.Column="3"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
ItemsSource="{Binding Items}"
|
ItemsSource="{Binding Items}"
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock Grid.Column="0" Text="{Binding Index,StringFormat=agr{0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="0" Text="{Binding Index,StringFormat=agr{0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center"/>
|
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center"/>
|
||||||
<TextBlock Grid.Column="2" MinWidth="50" Text="{Binding ParameterName}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="2" MinWidth="50" Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
<TextBox Grid.Column="3" MinWidth="50" Text="{Binding DataValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
|
<TextBox Grid.Column="3" MinWidth="50" Text="{Binding DataValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|||||||
Reference in New Issue
Block a user