From 8d0258ebea3df0990748ef0c538196abcf6e249e Mon Sep 17 00:00:00 2001 From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com> Date: Sat, 14 Dec 2024 23:46:37 +0800 Subject: [PATCH] =?UTF-8?q?Workbench=E9=A1=B9=E7=9B=AE=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86=E8=8A=82=E7=82=B9=E7=9A=84=E5=A4=8D?= =?UTF-8?q?=E5=88=B6=E3=80=81=E7=B2=98=E8=B4=B4=EF=BC=8C=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Library/FlowNode/NodeModelBaseFunc.cs | 139 +++--- Library/FlowNode/ParameterDetails.cs | 20 +- NodeFlow/Env/FlowEnvironment.cs | 2 +- NodeFlow/Model/SingleConditionNode.cs | 2 +- NodeFlow/Model/SingleExpOpNode.cs | 2 +- NodeFlow/Tool/NodeMethodDetailsHelper.cs | 18 +- WorkBench/MainWindow.xaml | 12 +- WorkBench/MainWindow.xaml.cs | 405 ++++++++++-------- WorkBench/Node/View/ActionNodeControl.xaml | 52 +-- WorkBench/Node/View/ActionNodeControl.xaml.cs | 2 + .../Node/Junction/JunctionControlBase.cs | 20 +- .../Node/Junction/View/ArgJunctionControl.cs | 4 +- .../Junction/View/ExecuteJunctionControl.cs | 4 +- .../Junction/View/NextStepJunctionControl.cs | 4 +- .../Junction/View/ResultJunctionControl.cs | 4 +- Workbench/Node/NodeControlBase.cs | 1 + Workbench/Node/View/ConnectionControl.cs | 3 - 17 files changed, 396 insertions(+), 298 deletions(-) diff --git a/Library/FlowNode/NodeModelBaseFunc.cs b/Library/FlowNode/NodeModelBaseFunc.cs index ac7fd69..35097e9 100644 --- a/Library/FlowNode/NodeModelBaseFunc.cs +++ b/Library/FlowNode/NodeModelBaseFunc.cs @@ -28,7 +28,26 @@ namespace Serein.Library /// public abstract partial class NodeModelBase : IDynamicFlowNode { - #region 节点移除相关 + #region 节点相关事件 + + /// + /// 保存自定义信息 + /// + /// + public virtual NodeInfo SaveCustomData(NodeInfo nodeInfo) + { + return nodeInfo; + } + + /// + /// 加载自定义数据 + /// + /// + public virtual void LoadCustomData(NodeInfo nodeInfo) + { + return; + } + /// /// 移除该节点 /// @@ -36,16 +55,52 @@ namespace Serein.Library { } + /// + /// 移除该节点 + /// + public virtual void RemoveFromEnv() + { + if (this.DebugSetting.CancelInterruptCallback != null) + { + this.DebugSetting.CancelInterruptCallback?.Invoke(); + } + this.DebugSetting.GetInterruptTask = null; + this.DebugSetting.NodeModel = null; + this.DebugSetting.CancelInterruptCallback = null; + this.DebugSetting = null; + foreach (var pd in this.MethodDetails.ParameterDetailss) + { + pd.DataValue = null; + pd.Items = null; + pd.NodeModel = null; + pd.ExplicitType = null; + pd.DataType = null; + pd.Name = null; + pd.ArgDataSourceNodeGuid = null; + pd.ExplicitTypeName = null; + } + this.MethodDetails.ParameterDetailss = null; + this.MethodDetails.ActingInstance = null; + this.MethodDetails.NodeModel = null; + this.MethodDetails.ReturnType = null; + this.MethodDetails.AssemblyName = null; + this.MethodDetails.MethodAnotherName = null; + this.MethodDetails.MethodLockName = null; + this.MethodDetails.MethodName = null; + this.MethodDetails.ActingInstanceType = null; + this.MethodDetails = null; + this.Position = null; + this.DisplayName = null; - #endregion + this.Env = null; + } - #region 导出/导入项目文件节点信息 /// /// 输出方法参数信息 /// /// - public virtual ParameterData[] SaveParameterInfo() + public ParameterData[] SaveParameterInfo() { if(MethodDetails.ParameterDetailss == null) { @@ -69,20 +124,13 @@ namespace Serein.Library } } - /// - /// 保存自定义信息 - /// - /// - public virtual NodeInfo SaveCustomData(NodeInfo nodeInfo) - { - return nodeInfo; - } + /// /// 导出为节点信息 /// /// - public virtual NodeInfo ToInfo() + public NodeInfo ToInfo() { // if (MethodDetails == null) return null; @@ -110,25 +158,20 @@ namespace Serein.Library IsInterrupt = this.DebugSetting.IsInterrupt, IsEnable = this.DebugSetting.IsEnable, }; + nodeInfo.Position.X = Math.Round(nodeInfo.Position.X, 1); + nodeInfo.Position.Y = Math.Round(nodeInfo.Position.Y, 1); nodeInfo = SaveCustomData(nodeInfo); return nodeInfo; } - /// - /// 加载自定义数据 - /// - /// - public virtual void LoadCustomData(NodeInfo nodeInfo) - { - return; - } + /// /// 从节点信息加载节点 /// /// /// - public virtual void LoadInfo(NodeInfo nodeInfo) + public void LoadInfo(NodeInfo nodeInfo) { this.Guid = nodeInfo.Guid; this.Position = nodeInfo.Position ?? new PositionOfUI(0, 0);// 加载位置信息 @@ -520,33 +563,33 @@ namespace Serein.Library #endregion - #region 入参存在取值转换器,调用对应的转换器获取入参数据,如果获取成功(不为null)会跳过循环 - if (pd.ExplicitType.IsEnum && !(pd.Convertor is null)) - { - //var resultEnum = Enum.ToObject(ed.ExplicitType, ed.DataValue); - var resultEnum = Enum.Parse(pd.ExplicitType, pd.DataValue); - var value = pd.Convertor(resultEnum); - if (value is null) - { - throw new InvalidOperationException("转换器调用失败"); + //#region 入参存在取值转换器,调用对应的转换器获取入参数据,如果获取成功(不为null)会跳过循环 + //if (pd.ExplicitType.IsEnum && !(pd.Convertor is null)) + //{ + // //var resultEnum = Enum.ToObject(ed.ExplicitType, ed.DataValue); + // var resultEnum = Enum.Parse(pd.ExplicitType, pd.DataValue); + // var value = pd.Convertor(resultEnum); + // if (value is null) + // { + // throw new InvalidOperationException("转换器调用失败"); - } - else - { - if (hasParams) - { - paramsArgs.SetValue(value, paramsArgIndex++); - // 处理可选参数 - //paramsArgs[paramsArgIndex++] = value; - } - else - { - parameters[i] = value; - } - continue; - } - } - #endregion + // } + // else + // { + // if (hasParams) + // { + // paramsArgs.SetValue(value, paramsArgIndex++); + // // 处理可选参数 + // //paramsArgs[paramsArgIndex++] = value; + // } + // else + // { + // parameters[i] = value; + // } + // continue; + // } + //} + //#endregion #region 入参存在基于BinValue的类型转换器,获取枚举转换器中记录的类型,如果获取成功(不为null)会跳过循环 // 入参存在基于BinValue的类型转换器,获取枚举转换器中记录的类型 diff --git a/Library/FlowNode/ParameterDetails.cs b/Library/FlowNode/ParameterDetails.cs index 870404f..33601cb 100644 --- a/Library/FlowNode/ParameterDetails.cs +++ b/Library/FlowNode/ParameterDetails.cs @@ -35,11 +35,11 @@ namespace Serein.Library [PropertyInfo(IsNotification = true)] private bool _isExplicitData ; - /// - /// 转换器 IEnumConvertor<,> - /// - [PropertyInfo] - private Func _convertor ; + ///// + ///// 转换器 IEnumConvertor<,> + ///// + //[PropertyInfo] + //private Func _convertor ; /// /// 方法入参若无相关转换器特性标注,则无需关注该变量。该变量用于需要用到枚举BinValue转换器时,指示相应的入参变量需要转为的类型。 @@ -167,7 +167,7 @@ namespace Serein.Library IsExplicitData = this.IsExplicitData, ExplicitType = this.ExplicitType, ExplicitTypeName = this.ExplicitTypeName, - Convertor = this.Convertor, + //Convertor = this.Convertor, DataType = this.DataType, Name = this.Name, DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue, @@ -180,14 +180,6 @@ namespace Serein.Library public override string ToString() { - if(_convertor is null) - { - return $"[{this.Index}] {this.Name} : {this.DataType?.FullName}"; - } - else - { - - } return $"[{this.Index}] {this.Name} : {this.ExplicitType.FullName} -> {this.DataType.FullName}"; } } diff --git a/NodeFlow/Env/FlowEnvironment.cs b/NodeFlow/Env/FlowEnvironment.cs index bfa4f56..1b7ecb0 100644 --- a/NodeFlow/Env/FlowEnvironment.cs +++ b/NodeFlow/Env/FlowEnvironment.cs @@ -918,7 +918,7 @@ namespace Serein.NodeFlow.Env else { // 加载方法节点 - if (string.IsNullOrEmpty(nodeInfo.AssemblyName) && string.IsNullOrEmpty(nodeInfo.MethodName)) + if (string.IsNullOrEmpty(nodeInfo.MethodName)) { continue; } diff --git a/NodeFlow/Model/SingleConditionNode.cs b/NodeFlow/Model/SingleConditionNode.cs index c71038f..ffe081a 100644 --- a/NodeFlow/Model/SingleConditionNode.cs +++ b/NodeFlow/Model/SingleConditionNode.cs @@ -65,7 +65,7 @@ namespace Serein.NodeFlow.Model ArgDataSourceNodeGuid = string.Empty, ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData, NodeModel = this, - Convertor = null, + //Convertor = null, ExplicitTypeName = "Value", Items = null, }; diff --git a/NodeFlow/Model/SingleExpOpNode.cs b/NodeFlow/Model/SingleExpOpNode.cs index 7e499e1..34ac24f 100644 --- a/NodeFlow/Model/SingleExpOpNode.cs +++ b/NodeFlow/Model/SingleExpOpNode.cs @@ -54,7 +54,7 @@ namespace Serein.NodeFlow.Model ArgDataSourceNodeGuid = string.Empty, ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData, NodeModel = this, - Convertor = null, + //Convertor = null, ExplicitTypeName = "Value", Items = null, }; diff --git a/NodeFlow/Tool/NodeMethodDetailsHelper.cs b/NodeFlow/Tool/NodeMethodDetailsHelper.cs index 8604f84..8dcf030 100644 --- a/NodeFlow/Tool/NodeMethodDetailsHelper.cs +++ b/NodeFlow/Tool/NodeMethodDetailsHelper.cs @@ -215,13 +215,14 @@ public static class NodeMethodDetailsHelper ConvertorInstance[key] = (instance, convertMethod); } - object func(object enumValue) - { - (var obj, var methodInfo) = ConvertorInstance[key]; - return methodInfo?.Invoke(obj, [enumValue]); - } + //object func(object enumValue) + //{ + // (var obj, var methodInfo) = ConvertorInstance[key]; + // return methodInfo?.Invoke(obj, [enumValue]); + //} + // 确保实例实现了所需接口 - ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true, func); // 自定义的转换器 获取参数 + ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true); // 自定义的转换器 获取参数 return ed; } @@ -242,8 +243,7 @@ public static class NodeMethodDetailsHelper private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo, int index, Type explicitParemType, - bool isExplicitData, - Func func = null) + bool isExplicitData) { bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数 @@ -269,7 +269,7 @@ public static class NodeMethodDetailsHelper Index = index, // 索引 ExplicitTypeName = explicitTypeName, // Select/Bool/Value ExplicitType = explicitParemType,// 显示的入参类型 - Convertor = func, // 转换器 + //Convertor = func, // 转换器 DataType = dataType, // 实际的入参类型 Name = parameterInfo.Name, DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值 diff --git a/WorkBench/MainWindow.xaml b/WorkBench/MainWindow.xaml index 1f49ba4..fcfea56 100644 --- a/WorkBench/MainWindow.xaml +++ b/WorkBench/MainWindow.xaml @@ -102,17 +102,23 @@ + + + + + + + + { + EnvDecorator.LoadProject(new FlowEnvInfo { Project = App.FlowProjectData }, App.FileDataPath); // 加载项目 + }); + } } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { @@ -659,15 +665,17 @@ namespace Serein.Workbench } } + + FlowChartCanvas.Children.Remove(nodeControl); nodeControl.RemoveAllConection(); NodeControls.Remove(nodeControl.ViewModel.NodeModel.Guid); } /// - /// 编辑项目时添加了节点 + /// 添加节点事件 /// - /// + /// 添加节点事件参数 /// private void FlowEnvironment_NodeCreateEvent(NodeCreateEventArgs eventArgs) { @@ -738,6 +746,8 @@ namespace Serein.Workbench NodeTreeViewer.AddGlobalFlipFlop(EnvDecorator, node); // 新增的触发器节点添加到全局触发器 } } + + GC.Collect(); #endregion } @@ -819,7 +829,10 @@ namespace Serein.Workbench //{ // nodeControl.ViewModel.IsInterrupt = true; //} - + if(nodeControl.ContextMenu == null) + { + return; + } foreach (var menuItem in nodeControl.ContextMenu.Items) { if (menuItem is MenuItem menu) @@ -2669,147 +2682,16 @@ namespace Serein.Workbench #region 复制粘贴选择的节点 if (Keyboard.Modifiers == ModifierKeys.Control) { - #region 复制节点 if (e.Key == Key.C && selectNodeControls.Count > 0) { - // 处理复制操作 - List selectNodeInfos = selectNodeControls.Select(control => control.ViewModel.NodeModel.ToInfo()).ToList(); - - /*foreach (var node in selectNodeInfos.ToArray()) - { - // 遍历这些节点的子节点,获得完整的已选节点信息 - foreach (var childNodeGuid in node.ChildNodeGuids) - { - if (!string.IsNullOrEmpty(childNodeGuid) - && NodeControls.TryGetValue(childNodeGuid, out var nodeControl)) - { - - var newNodeInfo = nodeControl.ViewModel.NodeModel.ToInfo(); - selectNodeInfos.Add(newNodeInfo); - } - } - }*/ - - - Dictionary guids = new Dictionary(); // 记录 Guid - // 遍历当前已选节点 - foreach (var node in selectNodeInfos.ToArray()) - { - if (!guids.ContainsKey(node.Guid)) - { - // 如果是没出现过的Guid,则记录并新增对应的映射。 - guids.TryAdd(node.Guid, Guid.NewGuid().ToString()); - } - else - { - // 出现过的Guid,说明重复添加了。应该不会走到这。 - continue; - } - - if(node.ChildNodeGuids is null) - { - continue; // 跳过没有子节点的节点 - } - - // 遍历这些节点的子节点,获得完整的已选节点信息 - foreach (var childNodeGuid in node.ChildNodeGuids) - { - if (!guids.ContainsKey(childNodeGuid)) - { - // 如果是没出现过的Guid,则记录并新增对应的映射。 - guids.TryAdd(node.Guid, Guid.NewGuid().ToString()); - } - - if (!string.IsNullOrEmpty(childNodeGuid) - && NodeControls.TryGetValue(childNodeGuid, out var nodeControl)) - { - - var newNodeInfo = nodeControl.ViewModel.NodeModel.ToInfo(); - selectNodeInfos.Add(newNodeInfo); - } - } - } - - var replacer = new GuidReplacer(); - foreach(var kv in guids) - { - replacer.AddReplacement(kv.Key, kv.Value); - } - - JObject json = new JObject() - { - ["nodes"] = JArray.FromObject(selectNodeInfos) - }; - var jsonText = json.ToString(); - - string result = replacer.Replace(jsonText); - - try - { - Clipboard.SetDataObject(result, true); // 持久性设置 - SereinEnv.WriteLine(InfoType.INFO, $"复制已选节点({selectNodeInfos.Count}个)"); - } - catch (Exception ex) - { - SereinEnv.WriteLine(InfoType.ERROR, $"复制失败:{ex.Message}"); - } - - //SereinEnv.WriteLine(InfoType.INFO, json.ToString()); - e.Handled = true; + CpoyNodeInfo(); } - #endregion - - #region 粘贴节点 else if (e.Key == Key.V) { - - if (Clipboard.ContainsText()) - { - string clipboardText = Clipboard.GetText(TextDataFormat.Text); - - List nodes = JsonConvert.DeserializeObject>(JObject.Parse(clipboardText)["nodes"].ToString()); - if (nodes is not null && nodes.Count >= 0) - { - Point mousePosition = Mouse.GetPosition(FlowChartCanvas); - PositionOfUI positionOfUI = new PositionOfUI(mousePosition.X, mousePosition.Y); // 坐标数据 - SereinEnv.WriteLine(InfoType.INFO, $"粘贴节点({nodes.Count}个)"); - // 获取第一个节点的原始位置 - var index0NodeX = nodes[0].Position.X; - var index0NodeY = nodes[0].Position.Y; - - // 计算所有节点相对于第一个节点的偏移量 - foreach (var node in nodes) - { - - var offsetX = node.Position.X - index0NodeX; - var offsetY = node.Position.Y - index0NodeY; - - // 根据鼠标位置平移节点 - node.Position = new PositionOfUI(positionOfUI.X + offsetX, positionOfUI.Y + offsetY); - } - - _ = EnvDecorator.LoadNodeInfosAsync(nodes); - } - - - //SereinEnv.WriteLine(InfoType.INFO, $"剪贴板文本内容: {clipboardText}"); - } - else if (Clipboard.ContainsImage()) - { - var image = Clipboard.GetImage(); - } - else - { - SereinEnv.WriteLine(InfoType.INFO, "剪贴板中没有可识别的数据。"); - } - e.Handled = true; - } - #endregion - - return; - } + PasteNodeInfo(); + } + } #endregion - if (e.KeyStates == Keyboard.GetKeyStates(Key.Escape)) { IsControlDragging = false; @@ -2860,9 +2742,219 @@ namespace Serein.Workbench } + #region 复制节点,粘贴节点 + + /// + /// 复制节点 + /// + private void CpoyNodeInfo() + { + // 处理复制操作 + var dictSelection = selectNodeControls + .Select(control => control.ViewModel.NodeModel.ToInfo()) + .ToDictionary(kvp => kvp.Guid, kvp => kvp); + + // 遍历当前已选节点 + foreach (var node in dictSelection.Values.ToArray()) + { + // 遍历这些节点的子节点,获得完整的已选节点信息 + foreach (var childNodeGuid in node.ChildNodeGuids) + { + if(!dictSelection.ContainsKey(childNodeGuid) && NodeControls.TryGetValue(childNodeGuid,out var childNode)) + { + dictSelection.Add(childNodeGuid, childNode.ViewModel.NodeModel.ToInfo()); + } + } + } + + + JObject json = new JObject() + { + ["nodes"] = JArray.FromObject(dictSelection.Values) + }; + + var jsonText = json.ToString(); + + + try + { + //Clipboard.SetDataObject(result, true); // 持久性设置 + Clipboard.SetDataObject(jsonText, true); // 持久性设置 + SereinEnv.WriteLine(InfoType.INFO, $"复制已选节点({dictSelection.Count}个)"); + } + catch (Exception ex) + { + SereinEnv.WriteLine(InfoType.ERROR, $"复制失败:{ex.Message}"); + } + } + + /// + /// 粘贴节点 + /// + private void PasteNodeInfo() + { + if (Clipboard.ContainsText()) + { + try + { + + string clipboardText = Clipboard.GetText(TextDataFormat.Text); + string jsonText = JObject.Parse(clipboardText)["nodes"].ToString(); + List nodes = JsonConvert.DeserializeObject>(jsonText); + if (nodes is null || nodes.Count < 0) + { + return; + } + + #region 节点去重 + Dictionary guids = new Dictionary(); // 记录 Guid + // 遍历当前已选节点 + foreach (var node in nodes.ToArray()) + { + if (NodeControls.ContainsKey(node.Guid) && !guids.ContainsKey(node.Guid)) + { + // 如果是没出现过、且在当前记录中重复的Guid,则记录并新增对应的映射。 + guids.TryAdd(node.Guid, Guid.NewGuid().ToString()); + } + else + { + // 出现过的Guid,说明重复添加了。应该不会走到这。 + continue; + } + + if (node.ChildNodeGuids is null) + { + continue; // 跳过没有子节点的节点 + } + + // 遍历这些节点的子节点,获得完整的已选节点信息 + foreach (var childNodeGuid in node.ChildNodeGuids) + { + if (NodeControls.ContainsKey(node.Guid) && !NodeControls.ContainsKey(node.Guid)) + { + // 当前Guid并不重复,跳过替换 + continue; + } + if (!guids.ContainsKey(childNodeGuid)) + { + // 如果是没出现过的Guid,则记录并新增对应的映射。 + guids.TryAdd(node.Guid, Guid.NewGuid().ToString()); + } + + if (!string.IsNullOrEmpty(childNodeGuid) + && NodeControls.TryGetValue(childNodeGuid, out var nodeControl)) + { + + var newNodeInfo = nodeControl.ViewModel.NodeModel.ToInfo(); + nodes.Add(newNodeInfo); + } + } + } + + //var flashText = new FlashText.NET.TextReplacer(); + + //var t = guids.Select(kvp => (kvp.Key, kvp.Value)).ToArray(); + //var result = flashText.ReplaceWords(jsonText, t); + + + + + + StringBuilder sb = new StringBuilder(jsonText); + foreach (var kv in guids) + { + sb.Replace(kv.Key, kv.Value); + } + string result = sb.ToString(); + + + /*var replacer = new GuidReplacer(); + foreach (var kv in guids) + { + replacer.AddReplacement(kv.Key, kv.Value); + } + string result = replacer.Replace(jsonText);*/ + + + //SereinEnv.WriteLine(InfoType.ERROR, result); + nodes = JsonConvert.DeserializeObject>(result); + + if (nodes is null || nodes.Count < 0) + { + return; + } + #endregion + + Point mousePosition = Mouse.GetPosition(FlowChartCanvas); + PositionOfUI positionOfUI = new PositionOfUI(mousePosition.X, mousePosition.Y); // 坐标数据 + + // 获取第一个节点的原始位置 + var index0NodeX = nodes[0].Position.X; + var index0NodeY = nodes[0].Position.Y; + + // 计算所有节点相对于第一个节点的偏移量 + foreach (var node in nodes) + { + + var offsetX = node.Position.X - index0NodeX; + var offsetY = node.Position.Y - index0NodeY; + + // 根据鼠标位置平移节点 + node.Position = new PositionOfUI(positionOfUI.X + offsetX, positionOfUI.Y + offsetY); + } + + _ = EnvDecorator.LoadNodeInfosAsync(nodes); + } + catch (Exception ex) + { + + SereinEnv.WriteLine(InfoType.ERROR, $"粘贴节点时发生异常:{ex}"); + } + + + // SereinEnv.WriteLine(InfoType.INFO, $"剪贴板文本内容: {clipboardText}"); + } + else if (Clipboard.ContainsImage()) + { + // var image = Clipboard.GetImage(); + } + else + { + SereinEnv.WriteLine(InfoType.INFO, "剪贴板中没有可识别的数据。"); + } + } + + #endregion /// + /// 卸载DLL文件,清空当前项目 + /// + /// + /// + private void UnloadAllButton_Click(object sender, RoutedEventArgs e) + { + EnvDecorator.ClearAll(); + } + + /// + /// 卸载DLL文件,清空当前项目 + /// + private void UnloadAllAssemblies() + { + DllStackPanel.Children.Clear(); + FlowChartCanvas.Children.Clear(); + Connections.Clear(); + NodeControls.Clear(); + //currentLine = null; + //startConnectNodeControl = null; + MessageBox.Show("所有DLL已卸载。", "信息", MessageBoxButton.OK, MessageBoxImage.Information); + } + + + + + /* /// /// 对象装箱测试 /// /// @@ -2913,31 +3005,6 @@ namespace Serein.Workbench data = SerinExpressionEvaluator.Evaluate(exp,result!, out isChange); SereinEnv.WriteLine(InfoType.INFO, $"{exp} => {data}"); } - - /// - /// 卸载DLL文件,清空当前项目 - /// - /// - /// - private void UnloadAllButton_Click(object sender, RoutedEventArgs e) - { - EnvDecorator.ClearAll(); - } - - /// - /// 卸载DLL文件,清空当前项目 - /// - private void UnloadAllAssemblies() - { - DllStackPanel.Children.Clear(); - FlowChartCanvas.Children.Clear(); - Connections.Clear(); - NodeControls.Clear(); - //currentLine = null; - //startConnectNodeControl = null; - MessageBox.Show("所有DLL已卸载。", "信息", MessageBoxButton.OK, MessageBoxImage.Information); - } - - +*/ } } \ No newline at end of file diff --git a/WorkBench/Node/View/ActionNodeControl.xaml b/WorkBench/Node/View/ActionNodeControl.xaml index e5fc3b4..fb71a3f 100644 --- a/WorkBench/Node/View/ActionNodeControl.xaml +++ b/WorkBench/Node/View/ActionNodeControl.xaml @@ -19,7 +19,7 @@ - + @@ -32,17 +32,14 @@ @@ -50,9 +47,6 @@ - - - @@ -62,10 +56,6 @@ - - - - @@ -79,19 +69,11 @@ - - - - - - - - + - + Converter={StaticResource InvertedBoolConverter}, ConverterParameter=Normal}" /> + @@ -110,20 +92,20 @@ - + - + - + - + - + - + @@ -131,10 +113,6 @@ - - - - diff --git a/WorkBench/Node/View/ActionNodeControl.xaml.cs b/WorkBench/Node/View/ActionNodeControl.xaml.cs index 8619d87..f26e7ba 100644 --- a/WorkBench/Node/View/ActionNodeControl.xaml.cs +++ b/WorkBench/Node/View/ActionNodeControl.xaml.cs @@ -72,6 +72,8 @@ namespace Serein.Workbench.Node.View return []; } } + + } diff --git a/Workbench/Node/Junction/JunctionControlBase.cs b/Workbench/Node/Junction/JunctionControlBase.cs index ac36a46..5ce870c 100644 --- a/Workbench/Node/Junction/JunctionControlBase.cs +++ b/Workbench/Node/Junction/JunctionControlBase.cs @@ -15,7 +15,21 @@ using System.Threading; namespace Serein.Workbench.Node.View { + internal static class MyUIFunc + { + public static Pen CreateAndFreezePen() + { + // 创建Pen + Pen pen = new Pen(Brushes.Black, 1); + // 冻结Pen + if (pen.CanFreeze) + { + pen.Freeze(); + } + return pen; + } + } public class ParamsArgControl: Shape { @@ -27,8 +41,6 @@ namespace Serein.Workbench.Node.View this.MouseMove += ParamsArgControl_MouseMove; this.MouseLeave += ParamsArgControl_MouseLeave; AddOrRemoveParamsTask = AddAsync; - - } @@ -84,9 +96,9 @@ namespace Serein.Workbench.Node.View // 圆形部分 var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2); - drawingContext.DrawGeometry(brush, new Pen(Brushes.Black, 1), ellipse); + drawingContext.DrawGeometry(brush, MyUIFunc.CreateAndFreezePen(), ellipse); } - + private bool isMouseOver; // 鼠标悬停状态 diff --git a/Workbench/Node/Junction/View/ArgJunctionControl.cs b/Workbench/Node/Junction/View/ArgJunctionControl.cs index d2f67ee..6ef6927 100644 --- a/Workbench/Node/Junction/View/ArgJunctionControl.cs +++ b/Workbench/Node/Junction/View/ArgJunctionControl.cs @@ -50,7 +50,7 @@ namespace Serein.Workbench.Node.View // 绘制连接器的圆形部分 var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2); - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse); // 定义三角形的间距 double triangleOffsetX = 4; // 三角形与圆形的间距 @@ -66,7 +66,7 @@ namespace Serein.Workbench.Node.View context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false); context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false); } - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry); } } diff --git a/Workbench/Node/Junction/View/ExecuteJunctionControl.cs b/Workbench/Node/Junction/View/ExecuteJunctionControl.cs index c9309e4..9247df1 100644 --- a/Workbench/Node/Junction/View/ExecuteJunctionControl.cs +++ b/Workbench/Node/Junction/View/ExecuteJunctionControl.cs @@ -46,7 +46,7 @@ namespace Serein.Workbench.Node.View var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2); - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse); @@ -65,7 +65,7 @@ namespace Serein.Workbench.Node.View context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false); context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false); } - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry); // 绘制标签 //var formattedText = new FormattedText( diff --git a/Workbench/Node/Junction/View/NextStepJunctionControl.cs b/Workbench/Node/Junction/View/NextStepJunctionControl.cs index 9dd1e65..7c5bde9 100644 --- a/Workbench/Node/Junction/View/NextStepJunctionControl.cs +++ b/Workbench/Node/Junction/View/NextStepJunctionControl.cs @@ -34,7 +34,7 @@ namespace Serein.Workbench.Node.View var circlePoint = new Point(circleCenterX, circleCenterY); // 绘制连接器的圆形部分 var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2); - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse); // 绘制连接器的圆形部分 //var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2); @@ -54,7 +54,7 @@ namespace Serein.Workbench.Node.View context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false); context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false); } - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry); } } } diff --git a/Workbench/Node/Junction/View/ResultJunctionControl.cs b/Workbench/Node/Junction/View/ResultJunctionControl.cs index 4e7f6db..aaad0d3 100644 --- a/Workbench/Node/Junction/View/ResultJunctionControl.cs +++ b/Workbench/Node/Junction/View/ResultJunctionControl.cs @@ -39,7 +39,7 @@ namespace Serein.Workbench.Node.View // 绘制连接器的圆形部分 var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2); - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse); // 定义三角形的间距 double triangleOffsetX = 4; // 三角形与圆形的间距 @@ -55,7 +55,7 @@ namespace Serein.Workbench.Node.View context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false); context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false); } - drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry); + drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry); } } } diff --git a/Workbench/Node/NodeControlBase.cs b/Workbench/Node/NodeControlBase.cs index d09e8b2..4d3cf09 100644 --- a/Workbench/Node/NodeControlBase.cs +++ b/Workbench/Node/NodeControlBase.cs @@ -22,6 +22,7 @@ namespace Serein.Workbench.Node.View public NodeControlViewModelBase ViewModel { get; set; } + protected NodeControlBase() { this.Background = Brushes.Transparent; diff --git a/Workbench/Node/View/ConnectionControl.cs b/Workbench/Node/View/ConnectionControl.cs index 0ca021a..ba32140 100644 --- a/Workbench/Node/View/ConnectionControl.cs +++ b/Workbench/Node/View/ConnectionControl.cs @@ -103,9 +103,6 @@ namespace Serein.Workbench.Node.View /// public class ConnectionControl { - - - /// /// 所在的画布 ///