From e4aa3b6185765b67af67875e2c9b6aa5e32a392d Mon Sep 17 00:00:00 2001
From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com>
Date: Mon, 30 Sep 2024 22:20:02 +0800
Subject: [PATCH] =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E5=B7=A5=E7=A8=8B=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E6=8F=90=E5=8D=87=E8=87=B3net462=EF=BC=8C=E9=A1=B9?=
=?UTF-8?q?=E7=9B=AE=E6=B7=BB=E5=8A=A0=E4=BA=86=E9=83=A8=E5=88=86=E7=A9=BA?=
=?UTF-8?q?=E5=BC=95=E7=94=A8=E6=A3=80=E6=B5=8B=E9=80=BB=E8=BE=91=E3=80=82?=
=?UTF-8?q?=E7=B4=AF=E4=BA=86=EF=BC=8C=E6=B6=88=E4=B8=8D=E5=AE=8C=E7=9A=84?=
=?UTF-8?q?=E7=A9=BA=E5=BC=95=E7=94=A8=E8=AD=A6=E5=91=8A(T.T=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Serein.Library.Framework.csproj | 2 +-
Library/Serein.Library.csproj | 2 +-
Library/Utils/ChannelFlowInterrupt.cs | 339 +++++++++---------
Library/Web/Router.cs | 1 +
.../Device/PrakingDevice.cs | 4 +-
.../Device/SiemensPlcDevice.cs | 6 +-
.../Enums/FromValue.cs | 4 +-
.../Enums/PlcState.cs | 2 +-
.../Enums/PlcVarEnum.cs | 6 +-
.../LogicControl/ParkingLogicControl.cs | 8 +-
.../LogicControl/PlcLogicControl.cs | 10 +-
.../LogicControl/ViewLogicControl.cs | 8 +-
.../Net462DllTest.csproj | 6 +-
.../Signal/CommandSignal.cs | 2 +-
.../Signal/PLCVarSignal.cs | 4 +-
.../Utils/ToValue.cs | 4 +-
.../View/FromWorkBenchView.Designer.cs | 2 +-
.../View/FromWorkBenchView.cs | 8 +-
.../View/FromWorkBenchView.resx | 0
.../View/TestFormView.Designer.cs | 2 +-
.../View/TestFormView.cs | 2 +-
.../View/TestFormView.resx | 0
.../ViewModel/FromWorkBenchViewModel.cs | 6 +-
.../Web/CommandController.cs | 0
.../Web/CommandController_1.cs | 6 +-
{Net461DllTest => Net462DllTest}/app.config | 8 +-
.../packages.config | 0
NodeFlow/Base/NodeModelBaseData.cs | 6 +-
NodeFlow/Base/NodeModelBaseFunc.cs | 90 ++---
NodeFlow/FlowEnvironment.cs | 78 ++--
NodeFlow/Model/CompositeActionNode.cs | 2 +-
NodeFlow/Tool/MethodDetailsHelper.cs | 2 +-
NodeFlow/Tool/ObjDynamicCreateHelper.cs | 55 ++-
.../Resolver/MemberStringConditionResolver.cs | 2 +-
.../SereinExpression/SereinConditionParser.cs | 4 +-
.../SerinExpressionEvaluator.cs | 143 ++++----
SereinFlow.sln | 2 +-
WorkBench/App.xaml.cs | 32 +-
WorkBench/MainWindow.xaml.cs | 209 +++++------
.../Node/View/ConditionRegionControl.xaml.cs | 1 -
.../Themes/NodeTreeItemViewControl.xaml.cs | 10 +-
WorkBench/Themes/NodeTreeViewControl.xaml.cs | 1 -
WorkBench/Themes/ObjectViewerControl.xaml.cs | 58 +--
WorkBench/Themes/TypeViewerWindow.xaml.cs | 4 +-
.../InvertableBooleanToVisibilityConverter.cs | 2 +-
45 files changed, 562 insertions(+), 581 deletions(-)
rename {Net461DllTest => Net462DllTest}/Device/PrakingDevice.cs (81%)
rename {Net461DllTest => Net462DllTest}/Device/SiemensPlcDevice.cs (99%)
rename {Net461DllTest => Net462DllTest}/Enums/FromValue.cs (85%)
rename {Net461DllTest => Net462DllTest}/Enums/PlcState.cs (94%)
rename {Net461DllTest => Net462DllTest}/Enums/PlcVarEnum.cs (96%)
rename {Net461DllTest => Net462DllTest}/LogicControl/ParkingLogicControl.cs (94%)
rename {Net461DllTest => Net462DllTest}/LogicControl/PlcLogicControl.cs (97%)
rename {Net461DllTest => Net462DllTest}/LogicControl/ViewLogicControl.cs (95%)
rename Net461DllTest/Net461DllTest.csproj => Net462DllTest/Net462DllTest.csproj (97%)
rename {Net461DllTest => Net462DllTest}/Signal/CommandSignal.cs (86%)
rename {Net461DllTest => Net462DllTest}/Signal/PLCVarSignal.cs (94%)
rename {Net461DllTest => Net462DllTest}/Utils/ToValue.cs (99%)
rename {Net461DllTest => Net462DllTest}/View/FromWorkBenchView.Designer.cs (99%)
rename {Net461DllTest => Net462DllTest}/View/FromWorkBenchView.cs (93%)
rename {Net461DllTest => Net462DllTest}/View/FromWorkBenchView.resx (100%)
rename {Net461DllTest => Net462DllTest}/View/TestFormView.Designer.cs (98%)
rename {Net461DllTest => Net462DllTest}/View/TestFormView.cs (90%)
rename {Net461DllTest => Net462DllTest}/View/TestFormView.resx (100%)
rename {Net461DllTest => Net462DllTest}/ViewModel/FromWorkBenchViewModel.cs (88%)
rename {Net461DllTest => Net462DllTest}/Web/CommandController.cs (100%)
rename {Net461DllTest => Net462DllTest}/Web/CommandController_1.cs (92%)
rename {Net461DllTest => Net462DllTest}/app.config (61%)
rename {Net461DllTest => Net462DllTest}/packages.config (100%)
diff --git a/Library.Framework/Serein.Library.Framework.csproj b/Library.Framework/Serein.Library.Framework.csproj
index 5332cb5..5d7f938 100644
--- a/Library.Framework/Serein.Library.Framework.csproj
+++ b/Library.Framework/Serein.Library.Framework.csproj
@@ -9,7 +9,7 @@
Properties
Serein.Library.Framework
Serein.Library.Framework
- v4.6.1
+ v4.6.2
512
true
diff --git a/Library/Serein.Library.csproj b/Library/Serein.Library.csproj
index 8f12865..cfe4b49 100644
--- a/Library/Serein.Library.csproj
+++ b/Library/Serein.Library.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;net461
+ netstandard2.0;net462
D:\Project\C#\DynamicControl\SereinFlow\.Output
diff --git a/Library/Utils/ChannelFlowInterrupt.cs b/Library/Utils/ChannelFlowInterrupt.cs
index c8e1402..d6fe5f0 100644
--- a/Library/Utils/ChannelFlowInterrupt.cs
+++ b/Library/Utils/ChannelFlowInterrupt.cs
@@ -7,196 +7,193 @@ using System.Threading.Tasks;
namespace Serein.Library.Utils
{
-///
-/// 流程中断管理
-///
-public class ChannelFlowInterrupt
-{
-
-
-
-///
-/// 中断取消类型
-///
-public enum CancelType
-{
- Manual,
- Error,
- Overtime
-}
-
-// 使用并发字典管理每个信号对应的 Channel
-private readonly ConcurrentDictionary> _channels = new ConcurrentDictionary>();
-
-///
-/// 创建信号并指定超时时间,到期后自动触发(异步方法)
-///
-/// 信号标识符
-/// 超时时间
-/// 等待任务
-public async Task GetCreateChannelWithTimeoutAsync(string signal, TimeSpan outTime)
-{
- var channel = GetOrCreateChannel(signal);
- var cts = new CancellationTokenSource();
-
- // 异步任务:超时后自动触发信号
- _ = Task.Run(async () =>
+ ///
+ /// 流程中断管理
+ ///
+ public class ChannelFlowInterrupt
{
- try
+ ///
+ /// 中断取消类型
+ ///
+ public enum CancelType
{
- await Task.Delay(outTime, cts.Token);
- if (!cts.Token.IsCancellationRequested)
+ Manual,
+ Error,
+ Overtime
+ }
+
+ // 使用并发字典管理每个信号对应的 Channel
+ private readonly ConcurrentDictionary> _channels = new ConcurrentDictionary>();
+
+ ///
+ /// 创建信号并指定超时时间,到期后自动触发(异步方法)
+ ///
+ /// 信号标识符
+ /// 超时时间
+ /// 等待任务
+ public async Task GetCreateChannelWithTimeoutAsync(string signal, TimeSpan outTime)
+ {
+ var channel = GetOrCreateChannel(signal);
+ var cts = new CancellationTokenSource();
+
+ // 异步任务:超时后自动触发信号
+ _ = Task.Run(async () =>
{
- await channel.Writer.WriteAsync(CancelType.Overtime);
+ try
+ {
+ await Task.Delay(outTime, cts.Token);
+ if (!cts.Token.IsCancellationRequested)
+ {
+ await channel.Writer.WriteAsync(CancelType.Overtime);
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ // 超时任务被取消
+ }
+ finally
+ {
+ cts?.Dispose();
+ }
+ }, cts.Token);
+
+ // 等待信号传入(超时或手动触发)
+ try
+ {
+ var result = await channel.Reader.ReadAsync();
+ return result;
}
+ catch
+ {
+ return CancelType.Error;
+ }
+
}
- catch (OperationCanceledException)
- {
- // 超时任务被取消
- }
- finally
- {
- cts?.Dispose();
- }
- }, cts.Token);
-
- // 等待信号传入(超时或手动触发)
- try
- {
- var result = await channel.Reader.ReadAsync();
- return result;
- }
- catch
- {
- return CancelType.Error;
- }
-
-}
-///
-/// 创建信号,直到手动触发(异步方法)
-///
-/// 信号标识符
-/// 超时时间
-/// 等待任务
-public async Task GetOrCreateChannelAsync(string signal)
-{
- try
- {
- var channel = GetOrCreateChannel(signal);
- // 等待信号传入(超时或手动触发)
- var result = await channel.Reader.ReadAsync();
- return result;
- }
- catch
- {
- return CancelType.Manual;
- }
-}
-
-///
-/// 创建信号并指定超时时间,到期后自动触发(同步阻塞方法)
-///
-/// 信号标识符
-/// 超时时间
-public CancelType CreateChannelWithTimeoutSync(string signal, TimeSpan timeout)
-{
- var channel = GetOrCreateChannel(signal);
- var cts = new CancellationTokenSource();
- CancellationToken token = cts.Token;
-
- // 异步任务:超时后自动触发信号
- _ = Task.Run(async () =>
+ ///
+ /// 创建信号,直到手动触发(异步方法)
+ ///
+ /// 信号标识符
+ /// 超时时间
+ /// 等待任务
+ public async Task GetOrCreateChannelAsync(string signal)
{
try
{
- await Task.Delay(timeout, token);
- await channel.Writer.WriteAsync(CancelType.Overtime);
+ var channel = GetOrCreateChannel(signal);
+ // 等待信号传入(超时或手动触发)
+ var result = await channel.Reader.ReadAsync();
+ return result;
}
- catch (OperationCanceledException ex)
+ catch
{
- // 任务被取消
- await Console.Out.WriteLineAsync(ex.Message);
+ return CancelType.Manual;
}
- });
-
- // 同步阻塞直到信号触发或超时
- var result = channel.Reader.ReadAsync().AsTask().GetAwaiter().GetResult();
- return result;
-
-}
-
-///
-/// 触发信号
-///
-/// 信号字符串
-/// 是否成功触发
-public bool TriggerSignal(string signal)
-{
- //if (_channels.TryGetValue(signal, out var channel))
- //{
- // // 手动触发信号
- // channel.Writer.TryWrite(CancelType.Manual);
- // return true;
- //}
- //return false;
-
-
- try
- {
- if (_channels.TryGetValue(signal, out var channel))
- {
- // 手动触发信号
- channel.Writer.TryWrite(CancelType.Manual);
-
- // 完成写入,标记该信号通道不再接受新写入
- channel.Writer.Complete();
-
- // 触发后移除信号
- _channels.TryRemove(signal, out _);
-
- return true;
}
- return false;
- }
- catch
- {
- return false;
- }
-
-}
-
-///
-/// 取消所有任务
-///
-public void CancelAllTasks()
-{
- foreach (var channel in _channels.Values)
- {
- try
- {
- channel.Writer.Complete();
- }
- finally
+ ///
+ /// 创建信号并指定超时时间,到期后自动触发(同步阻塞方法)
+ ///
+ /// 信号标识符
+ /// 超时时间
+ public CancelType CreateChannelWithTimeoutSync(string signal, TimeSpan timeout)
{
+ var channel = GetOrCreateChannel(signal);
+ var cts = new CancellationTokenSource();
+ CancellationToken token = cts.Token;
+
+ // 异步任务:超时后自动触发信号
+ _ = Task.Run(async () =>
+ {
+ try
+ {
+ await Task.Delay(timeout, token);
+ await channel.Writer.WriteAsync(CancelType.Overtime);
+ }
+ catch (OperationCanceledException ex)
+ {
+ // 任务被取消
+ await Console.Out.WriteLineAsync(ex.Message);
+ }
+ });
+
+ // 同步阻塞直到信号触发或超时
+ var result = channel.Reader.ReadAsync().AsTask().GetAwaiter().GetResult();
+ return result;
}
- }
- _channels.Clear();
-}
-///
-/// 获取或创建指定信号的 Channel
-///
-/// 信号字符串
-/// 对应的 Channel
-private Channel GetOrCreateChannel(string signal)
-{
- return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded());
-}
-}
+ ///
+ /// 触发信号
+ ///
+ /// 信号字符串
+ /// 是否成功触发
+ public bool TriggerSignal(string signal)
+ {
+ //if (_channels.TryGetValue(signal, out var channel))
+ //{
+ // // 手动触发信号
+ // channel.Writer.TryWrite(CancelType.Manual);
+ // return true;
+ //}
+ //return false;
+
+
+ try
+ {
+ if (_channels.TryGetValue(signal, out var channel))
+ {
+ // 手动触发信号
+ channel.Writer.TryWrite(CancelType.Manual);
+
+ // 完成写入,标记该信号通道不再接受新写入
+ channel.Writer.Complete();
+
+ // 触发后移除信号
+ _channels.TryRemove(signal, out _);
+
+ return true;
+ }
+ return false;
+ }
+ catch
+ {
+
+ return false;
+ }
+
+ }
+
+ ///
+ /// 取消所有任务
+ ///
+ public void CancelAllTasks()
+ {
+ foreach (var channel in _channels.Values)
+ {
+ try
+ {
+ channel.Writer.Complete();
+ }
+ finally
+ {
+
+ }
+ }
+ _channels.Clear();
+ }
+
+ ///
+ /// 获取或创建指定信号的 Channel
+ ///
+ /// 信号字符串
+ /// 对应的 Channel
+ private Channel GetOrCreateChannel(string signal)
+ {
+ return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded());
+ }
+ }
}
#endregion
diff --git a/Library/Web/Router.cs b/Library/Web/Router.cs
index a7318f3..15c1cfb 100644
--- a/Library/Web/Router.cs
+++ b/Library/Web/Router.cs
@@ -345,6 +345,7 @@ namespace Serein.Library.Web
}
catch (JsonReaderException ex)
{
+ Console.WriteLine(ex);
return value;
}
catch (JsonSerializationException ex)
diff --git a/Net461DllTest/Device/PrakingDevice.cs b/Net462DllTest/Device/PrakingDevice.cs
similarity index 81%
rename from Net461DllTest/Device/PrakingDevice.cs
rename to Net462DllTest/Device/PrakingDevice.cs
index e5b50aa..a76cf8b 100644
--- a/Net461DllTest/Device/PrakingDevice.cs
+++ b/Net462DllTest/Device/PrakingDevice.cs
@@ -1,4 +1,4 @@
-using Net461DllTest.LogicControl;
+using Net462DllTest.LogicControl;
using Serein.Library.Attributes;
using Serein.Library.NodeFlow.Tool;
using System;
@@ -7,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.Device
+namespace Net462DllTest.Device
{
[AutoRegister]
public class PrakingDevice : ChannelFlowTrigger
diff --git a/Net461DllTest/Device/SiemensPlcDevice.cs b/Net462DllTest/Device/SiemensPlcDevice.cs
similarity index 99%
rename from Net461DllTest/Device/SiemensPlcDevice.cs
rename to Net462DllTest/Device/SiemensPlcDevice.cs
index 4c711c6..2418fb9 100644
--- a/Net461DllTest/Device/SiemensPlcDevice.cs
+++ b/Net462DllTest/Device/SiemensPlcDevice.cs
@@ -1,13 +1,13 @@
using IoTClient;
using IoTClient.Clients.PLC;
using IoTClient.Enums;
-using Net461DllTest.Enums;
-using Net461DllTest.Signal;
+using Net462DllTest.Enums;
+using Net462DllTest.Signal;
using Serein.Library.Attributes;
using Serein.Library.NodeFlow.Tool;
using System;
-namespace Net461DllTest.Device
+namespace Net462DllTest.Device
{
///
diff --git a/Net461DllTest/Enums/FromValue.cs b/Net462DllTest/Enums/FromValue.cs
similarity index 85%
rename from Net461DllTest/Enums/FromValue.cs
rename to Net462DllTest/Enums/FromValue.cs
index 70cafbb..4bd6eda 100644
--- a/Net461DllTest/Enums/FromValue.cs
+++ b/Net462DllTest/Enums/FromValue.cs
@@ -1,4 +1,4 @@
-using Net461DllTest.View;
+using Net462DllTest.View;
using Serein.Library.Attributes;
using System;
using System.Collections.Generic;
@@ -6,7 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.Signal
+namespace Net462DllTest.Signal
{
public enum FromValue
{
diff --git a/Net461DllTest/Enums/PlcState.cs b/Net462DllTest/Enums/PlcState.cs
similarity index 94%
rename from Net461DllTest/Enums/PlcState.cs
rename to Net462DllTest/Enums/PlcState.cs
index 12e4eed..52a7be5 100644
--- a/Net461DllTest/Enums/PlcState.cs
+++ b/Net462DllTest/Enums/PlcState.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.Enums
+namespace Net462DllTest.Enums
{
public enum PlcState
{
diff --git a/Net461DllTest/Enums/PlcVarEnum.cs b/Net462DllTest/Enums/PlcVarEnum.cs
similarity index 96%
rename from Net461DllTest/Enums/PlcVarEnum.cs
rename to Net462DllTest/Enums/PlcVarEnum.cs
index 2ccaaf8..9c85f3f 100644
--- a/Net461DllTest/Enums/PlcVarEnum.cs
+++ b/Net462DllTest/Enums/PlcVarEnum.cs
@@ -1,12 +1,12 @@
-using Net461DllTest.Signal;
+using Net462DllTest.Signal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using static Net461DllTest.Signal.PlcValueAttribute;
+using static Net462DllTest.Signal.PlcValueAttribute;
-namespace Net461DllTest.Enums
+namespace Net462DllTest.Enums
{
diff --git a/Net461DllTest/LogicControl/ParkingLogicControl.cs b/Net462DllTest/LogicControl/ParkingLogicControl.cs
similarity index 94%
rename from Net461DllTest/LogicControl/ParkingLogicControl.cs
rename to Net462DllTest/LogicControl/ParkingLogicControl.cs
index 0b011cb..200309d 100644
--- a/Net461DllTest/LogicControl/ParkingLogicControl.cs
+++ b/Net462DllTest/LogicControl/ParkingLogicControl.cs
@@ -1,6 +1,6 @@
-using Net461DllTest.Device;
-using Net461DllTest.Signal;
-using Net461DllTest.ViewModel;
+using Net462DllTest.Device;
+using Net462DllTest.Signal;
+using Net462DllTest.ViewModel;
using Serein.Library.Api;
using Serein.Library.Attributes;
using Serein.Library.Enums;
@@ -13,7 +13,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.LogicControl
+namespace Net462DllTest.LogicControl
{
public enum ParkingCommand
diff --git a/Net461DllTest/LogicControl/PlcLogicControl.cs b/Net462DllTest/LogicControl/PlcLogicControl.cs
similarity index 97%
rename from Net461DllTest/LogicControl/PlcLogicControl.cs
rename to Net462DllTest/LogicControl/PlcLogicControl.cs
index 07caa0a..6624f20 100644
--- a/Net461DllTest/LogicControl/PlcLogicControl.cs
+++ b/Net462DllTest/LogicControl/PlcLogicControl.cs
@@ -1,9 +1,9 @@
using IoTClient.Clients.PLC;
using IoTClient.Common.Enums;
-using Net461DllTest.Device;
-using Net461DllTest.Enums;
-using Net461DllTest.Signal;
-using Net461DllTest.Web;
+using Net462DllTest.Device;
+using Net462DllTest.Enums;
+using Net462DllTest.Signal;
+using Net462DllTest.Web;
using Serein.Library.Api;
using Serein.Library.Attributes;
using Serein.Library.Enums;
@@ -18,7 +18,7 @@ using System.ComponentModel;
using System.Reflection;
using System.Threading.Tasks;
-namespace Net461DllTest.LogicControl
+namespace Net462DllTest.LogicControl
{
[AutoRegister]
[DynamicFlow]
diff --git a/Net461DllTest/LogicControl/ViewLogicControl.cs b/Net462DllTest/LogicControl/ViewLogicControl.cs
similarity index 95%
rename from Net461DllTest/LogicControl/ViewLogicControl.cs
rename to Net462DllTest/LogicControl/ViewLogicControl.cs
index 15aa626..6a47e59 100644
--- a/Net461DllTest/LogicControl/ViewLogicControl.cs
+++ b/Net462DllTest/LogicControl/ViewLogicControl.cs
@@ -1,6 +1,6 @@
-using Net461DllTest.Device;
-using Net461DllTest.Signal;
-using Net461DllTest.ViewModel;
+using Net462DllTest.Device;
+using Net462DllTest.Signal;
+using Net462DllTest.ViewModel;
using Serein.Library.Api;
using Serein.Library.Attributes;
using Serein.Library.Enums;
@@ -10,7 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
-namespace Net461DllTest.LogicControl
+namespace Net462DllTest.LogicControl
{
///
diff --git a/Net461DllTest/Net461DllTest.csproj b/Net462DllTest/Net462DllTest.csproj
similarity index 97%
rename from Net461DllTest/Net461DllTest.csproj
rename to Net462DllTest/Net462DllTest.csproj
index 05d0107..50a2c4a 100644
--- a/Net461DllTest/Net461DllTest.csproj
+++ b/Net462DllTest/Net462DllTest.csproj
@@ -6,9 +6,9 @@
AnyCPU
{E40EE629-1A38-4011-88E3-9AD036869987}
Library
- Net461DllTest
- Net461DllTest
- v4.6.1
+ Net462DllTest
+ Net462DllTest
+ v4.6.2
512
true
true
diff --git a/Net461DllTest/Signal/CommandSignal.cs b/Net462DllTest/Signal/CommandSignal.cs
similarity index 86%
rename from Net461DllTest/Signal/CommandSignal.cs
rename to Net462DllTest/Signal/CommandSignal.cs
index c8dfe50..98d0577 100644
--- a/Net461DllTest/Signal/CommandSignal.cs
+++ b/Net462DllTest/Signal/CommandSignal.cs
@@ -1,4 +1,4 @@
-namespace Net461DllTest.Signal
+namespace Net462DllTest.Signal
{
public enum CommandSignal
{
diff --git a/Net461DllTest/Signal/PLCVarSignal.cs b/Net462DllTest/Signal/PLCVarSignal.cs
similarity index 94%
rename from Net461DllTest/Signal/PLCVarSignal.cs
rename to Net462DllTest/Signal/PLCVarSignal.cs
index 9cb5a1c..e618fc0 100644
--- a/Net461DllTest/Signal/PLCVarSignal.cs
+++ b/Net462DllTest/Signal/PLCVarSignal.cs
@@ -1,8 +1,8 @@
using Serein.Library.Attributes;
using System;
-using static Net461DllTest.Signal.PlcValueAttribute;
+using static Net462DllTest.Signal.PlcValueAttribute;
-namespace Net461DllTest.Signal
+namespace Net462DllTest.Signal
{
[AttributeUsage(AttributeTargets.Field)]
diff --git a/Net461DllTest/Utils/ToValue.cs b/Net462DllTest/Utils/ToValue.cs
similarity index 99%
rename from Net461DllTest/Utils/ToValue.cs
rename to Net462DllTest/Utils/ToValue.cs
index db045ff..aea18bd 100644
--- a/Net461DllTest/Utils/ToValue.cs
+++ b/Net462DllTest/Utils/ToValue.cs
@@ -1,7 +1,7 @@
using IoTClient;
using IoTClient.Clients.PLC;
using IoTClient.Enums;
-using Net461DllTest.Signal;
+using Net462DllTest.Signal;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,7 +9,7 @@ using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.Utils
+namespace Net462DllTest.Utils
{
internal static class MyPlcExtension
{
diff --git a/Net461DllTest/View/FromWorkBenchView.Designer.cs b/Net462DllTest/View/FromWorkBenchView.Designer.cs
similarity index 99%
rename from Net461DllTest/View/FromWorkBenchView.Designer.cs
rename to Net462DllTest/View/FromWorkBenchView.Designer.cs
index caffe5e..451cd10 100644
--- a/Net461DllTest/View/FromWorkBenchView.Designer.cs
+++ b/Net462DllTest/View/FromWorkBenchView.Designer.cs
@@ -1,4 +1,4 @@
-namespace Net461DllTest
+namespace Net462DllTest
{
partial class FromWorkBenchView
{
diff --git a/Net461DllTest/View/FromWorkBenchView.cs b/Net462DllTest/View/FromWorkBenchView.cs
similarity index 93%
rename from Net461DllTest/View/FromWorkBenchView.cs
rename to Net462DllTest/View/FromWorkBenchView.cs
index ac47216..ad95f4b 100644
--- a/Net461DllTest/View/FromWorkBenchView.cs
+++ b/Net462DllTest/View/FromWorkBenchView.cs
@@ -1,6 +1,6 @@
-using Net461DllTest.Device;
-using Net461DllTest.Signal;
-using Net461DllTest.ViewModel;
+using Net462DllTest.Device;
+using Net462DllTest.Signal;
+using Net462DllTest.ViewModel;
using Serein.Library.Api;
using Serein.Library.Attributes;
using System;
@@ -13,7 +13,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
-namespace Net461DllTest
+namespace Net462DllTest
{
public partial class FromWorkBenchView : Form
{
diff --git a/Net461DllTest/View/FromWorkBenchView.resx b/Net462DllTest/View/FromWorkBenchView.resx
similarity index 100%
rename from Net461DllTest/View/FromWorkBenchView.resx
rename to Net462DllTest/View/FromWorkBenchView.resx
diff --git a/Net461DllTest/View/TestFormView.Designer.cs b/Net462DllTest/View/TestFormView.Designer.cs
similarity index 98%
rename from Net461DllTest/View/TestFormView.Designer.cs
rename to Net462DllTest/View/TestFormView.Designer.cs
index 41ea4a4..a27664b 100644
--- a/Net461DllTest/View/TestFormView.Designer.cs
+++ b/Net462DllTest/View/TestFormView.Designer.cs
@@ -1,6 +1,6 @@
using System;
-namespace Net461DllTest.View
+namespace Net462DllTest.View
{
partial class TestFormView
{
diff --git a/Net461DllTest/View/TestFormView.cs b/Net462DllTest/View/TestFormView.cs
similarity index 90%
rename from Net461DllTest/View/TestFormView.cs
rename to Net462DllTest/View/TestFormView.cs
index b747544..9fb49f3 100644
--- a/Net461DllTest/View/TestFormView.cs
+++ b/Net462DllTest/View/TestFormView.cs
@@ -1,7 +1,7 @@
using System;
using System.Windows.Forms;
-namespace Net461DllTest.View
+namespace Net462DllTest.View
{
public partial class TestFormView : Form
{
diff --git a/Net461DllTest/View/TestFormView.resx b/Net462DllTest/View/TestFormView.resx
similarity index 100%
rename from Net461DllTest/View/TestFormView.resx
rename to Net462DllTest/View/TestFormView.resx
diff --git a/Net461DllTest/ViewModel/FromWorkBenchViewModel.cs b/Net462DllTest/ViewModel/FromWorkBenchViewModel.cs
similarity index 88%
rename from Net461DllTest/ViewModel/FromWorkBenchViewModel.cs
rename to Net462DllTest/ViewModel/FromWorkBenchViewModel.cs
index 0c0fed2..38f3456 100644
--- a/Net461DllTest/ViewModel/FromWorkBenchViewModel.cs
+++ b/Net462DllTest/ViewModel/FromWorkBenchViewModel.cs
@@ -1,5 +1,5 @@
-using Net461DllTest.Device;
-using Net461DllTest.Signal;
+using Net462DllTest.Device;
+using Net462DllTest.Signal;
using Serein.Library.Attributes;
using System;
using System.Collections.Generic;
@@ -7,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.ViewModel
+namespace Net462DllTest.ViewModel
{
public class FromWorkBenchViewModel
{
diff --git a/Net461DllTest/Web/CommandController.cs b/Net462DllTest/Web/CommandController.cs
similarity index 100%
rename from Net461DllTest/Web/CommandController.cs
rename to Net462DllTest/Web/CommandController.cs
diff --git a/Net461DllTest/Web/CommandController_1.cs b/Net462DllTest/Web/CommandController_1.cs
similarity index 92%
rename from Net461DllTest/Web/CommandController_1.cs
rename to Net462DllTest/Web/CommandController_1.cs
index d4fc1c8..c840e00 100644
--- a/Net461DllTest/Web/CommandController_1.cs
+++ b/Net462DllTest/Web/CommandController_1.cs
@@ -1,5 +1,5 @@
-using Net461DllTest.Device;
-using Net461DllTest.Signal;
+using Net462DllTest.Device;
+using Net462DllTest.Signal;
using Serein.Library.Attributes;
using Serein.Library.Web;
using System;
@@ -8,7 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Net461DllTest.Web
+namespace Net462DllTest.Web
{
[AutoHosting]
public class CommandController : ControllerBase
diff --git a/Net461DllTest/app.config b/Net462DllTest/app.config
similarity index 61%
rename from Net461DllTest/app.config
rename to Net462DllTest/app.config
index dd1ad41..7a0cd6f 100644
--- a/Net461DllTest/app.config
+++ b/Net462DllTest/app.config
@@ -1,11 +1,11 @@
-
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/Net461DllTest/packages.config b/Net462DllTest/packages.config
similarity index 100%
rename from Net461DllTest/packages.config
rename to Net462DllTest/packages.config
diff --git a/NodeFlow/Base/NodeModelBaseData.cs b/NodeFlow/Base/NodeModelBaseData.cs
index 115b2d5..b8de691 100644
--- a/NodeFlow/Base/NodeModelBaseData.cs
+++ b/NodeFlow/Base/NodeModelBaseData.cs
@@ -41,12 +41,12 @@ namespace Serein.NodeFlow.Base
///
/// 节点guid
///
- public string Guid { get; set; }
+ public string Guid { get; set; } = string.Empty;
///
/// 显示名称
///
- public string DisplayName { get; set; }
+ public string DisplayName { get; set; } = string.Empty;
///
/// 是否为起点控件
@@ -76,7 +76,7 @@ namespace Serein.NodeFlow.Base
///
/// 运行时的异常信息(仅在 FlowState 为 Error 时存在对应值)
///
- public Exception RuningException { get; set; } = null;
+ public Exception? RuningException { get; set; } = null;
///
diff --git a/NodeFlow/Base/NodeModelBaseFunc.cs b/NodeFlow/Base/NodeModelBaseFunc.cs
index e7178f8..c788f90 100644
--- a/NodeFlow/Base/NodeModelBaseFunc.cs
+++ b/NodeFlow/Base/NodeModelBaseFunc.cs
@@ -74,17 +74,17 @@ namespace Serein.NodeFlow.Base
internal virtual NodeModelBase LoadInfo(NodeInfo nodeInfo)
{
- var node = this;
- if (node != null)
+ this.Guid = nodeInfo.Guid;
+ if(this.MethodDetails is not null)
{
- node.Guid = nodeInfo.Guid;
for (int i = 0; i < nodeInfo.ParameterData.Length; i++)
{
Parameterdata? pd = nodeInfo.ParameterData[i];
- node.MethodDetails.ExplicitDatas[i].IsExplicitData = pd.State;
- node.MethodDetails.ExplicitDatas[i].DataValue = pd.Value;
+ this.MethodDetails.ExplicitDatas[i].IsExplicitData = pd.State;
+ this.MethodDetails.ExplicitDatas[i].DataValue = pd.Value;
}
}
+
return this;
}
@@ -132,7 +132,7 @@ namespace Serein.NodeFlow.Base
if (upstreamNodes[i].DebugSetting.InterruptClass != InterruptClass.None) // 执行触发前
{
var cancelType = await upstreamNodes[i].DebugSetting.GetInterruptTask();
- await Console.Out.WriteLineAsync($"[{upstreamNodes[i].MethodDetails.MethodName}]中断已{cancelType},开始执行后继分支");
+ await Console.Out.WriteLineAsync($"[{upstreamNodes[i]?.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支");
}
upstreamNodes[i].PreviousNode = currentNode;
await upstreamNodes[i].StartExecute(context); // 执行流程节点的上游分支
@@ -165,7 +165,7 @@ namespace Serein.NodeFlow.Base
if (nextNodes[i].DebugSetting.InterruptClass != InterruptClass.None) // 执行触发前
{
var cancelType = await nextNodes[i].DebugSetting.GetInterruptTask();
- await Console.Out.WriteLineAsync($"[{nextNodes[i].MethodDetails.MethodName}]中断已{cancelType},开始执行后继分支");
+ await Console.Out.WriteLineAsync($"[{nextNodes[i]?.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支");
}
nextNodes[i].PreviousNode = currentNode;
stack.Push(nextNodes[i]);
@@ -194,18 +194,22 @@ namespace Serein.NodeFlow.Base
// this.NextOrientation = ConnectionType.None;
// return null;
//}
- await Console.Out.WriteLineAsync($"[{this.MethodDetails.MethodName}]中断已{cancelType},开始执行后继分支");
+ await Console.Out.WriteLineAsync($"[{this.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支");
}
#endregion
- MethodDetails md = MethodDetails;
+ MethodDetails? md = MethodDetails;
//var del = md.MethodDelegate.Clone();
+ if (md is null)
+ {
+ throw new Exception($"节点{this.Guid}不存在方法信息,请检查是否需要重写节点的ExecutingAsync");
+ }
if (!context.Env.TryGetDelegate(md.MethodName, out var del))
{
- throw new Exception("不存在对应委托");
+ throw new Exception($"节点{this.Guid}不存在对应委托");
}
- md.ActingInstance ??= context.Env.IOC.Get(MethodDetails.ActingInstanceType);
+ md.ActingInstance ??= context.Env.IOC.Get(md.ActingInstanceType);
object instance = md.ActingInstance;
var haveParameter = md.ExplicitDatas.Length > 0;
@@ -281,7 +285,7 @@ namespace Serein.NodeFlow.Base
if (ed.IsExplicitData) // 判断是否使用显示的输入参数
{
- if (ed.DataValue.StartsWith("@get", StringComparison.OrdinalIgnoreCase))
+ if (ed.DataValue.StartsWith("@get", StringComparison.OrdinalIgnoreCase) && flowData is not null)
{
// 执行表达式从上一节点获取对象
inputParameter = SerinExpressionEvaluator.Evaluate(ed.DataValue, flowData, out _);
@@ -315,8 +319,6 @@ namespace Serein.NodeFlow.Base
}
}
- //var attribute = ed.DataType.GetCustomAttribute();
- //if (attribute is not null && attribute.EnumType.IsEnum) // 获取枚举转换器中记录的枚举
if ( ed.DataType != ed.ExplicitType) // 获取枚举转换器中记录的枚举
{
if (ed.ExplicitType.IsEnum && Enum.TryParse(ed.ExplicitType, ed.DataValue, out var resultEnum)) // 获取对应的枚举项
@@ -339,41 +341,43 @@ namespace Serein.NodeFlow.Base
try
{
+ string? valueStr = inputParameter?.ToString();
parameters[i] = ed.DataType switch
{
- //Type t when t == previousDataType => inputParameter, // 上下文
- Type t when t.IsEnum => Enum.Parse(ed.DataType, ed.DataValue),// 需要枚举
Type t when t == typeof(IDynamicContext) => context, // 上下文
+ Type t when t.IsEnum => Enum.Parse(ed.DataType, ed.DataValue),// 需要枚举
+ Type t when t == typeof(string) => inputParameter?.ToString(),
+ Type t when t == typeof(char) && !string.IsNullOrEmpty(valueStr) => char.Parse(valueStr),
+ Type t when t == typeof(bool) && !string.IsNullOrEmpty(valueStr) => inputParameter is not null && bool.Parse(valueStr),
+ Type t when t == typeof(float) && !string.IsNullOrEmpty(valueStr) => float.Parse(valueStr),
+ Type t when t == typeof(decimal) && !string.IsNullOrEmpty(valueStr) => decimal.Parse(valueStr),
+ Type t when t == typeof(double) && !string.IsNullOrEmpty(valueStr) => double.Parse(valueStr),
+ Type t when t == typeof(sbyte) && !string.IsNullOrEmpty(valueStr) => sbyte.Parse(valueStr),
+ Type t when t == typeof(byte) && !string.IsNullOrEmpty(valueStr) => byte.Parse(valueStr),
+ Type t when t == typeof(short) && !string.IsNullOrEmpty(valueStr) => short.Parse(valueStr),
+ Type t when t == typeof(ushort) && !string.IsNullOrEmpty(valueStr) => ushort.Parse(valueStr),
+ Type t when t == typeof(int) && !string.IsNullOrEmpty(valueStr) => int.Parse(valueStr),
+ Type t when t == typeof(uint) && !string.IsNullOrEmpty(valueStr) => uint.Parse(valueStr),
+ Type t when t == typeof(long) && !string.IsNullOrEmpty(valueStr) => long.Parse(valueStr),
+ Type t when t == typeof(ulong) && !string.IsNullOrEmpty(valueStr) => ulong.Parse(valueStr),
+ Type t when t == typeof(nint) && !string.IsNullOrEmpty(valueStr) => nint.Parse(valueStr),
+ Type t when t == typeof(nuint) && !string.IsNullOrEmpty(valueStr) => nuint.Parse(valueStr),
+ //Type t when t == typeof(DateTime) => string.IsNullOrEmpty(valueStr) ? 0 : DateTime.Parse(valueStr),
+
Type t when t == typeof(MethodDetails) => md, // 节点方法描述
Type t when t == typeof(NodeModelBase) => nodeModel, // 节点实体类
- Type t when t == typeof(Guid) => new Guid(inputParameter?.ToString()),
- Type t when t == typeof(DateTime) => DateTime.Parse(inputParameter?.ToString()),
- Type t when t == typeof(string) => inputParameter?.ToString(),
- Type t when t == typeof(char) => char.Parse(inputParameter?.ToString()),
- Type t when t == typeof(bool) => inputParameter is null ? false : bool.Parse(inputParameter?.ToString()),
- Type t when t == typeof(float) => inputParameter is null ? 0F : float.Parse(inputParameter?.ToString()),
- Type t when t == typeof(decimal) => inputParameter is null ? 0 : decimal.Parse(inputParameter?.ToString()),
- Type t when t == typeof(double) => inputParameter is null ? 0 : double.Parse(inputParameter?.ToString()),
- Type t when t == typeof(sbyte) => inputParameter is null ? 0 : sbyte.Parse(inputParameter?.ToString()),
- Type t when t == typeof(byte) => inputParameter is null ? 0 : byte.Parse(inputParameter?.ToString()),
- Type t when t == typeof(short) => inputParameter is null ? 0 : short.Parse(inputParameter?.ToString()),
- Type t when t == typeof(ushort) => inputParameter is null ? 0U : ushort.Parse(inputParameter?.ToString()),
- Type t when t == typeof(int) => inputParameter is null ? 0 : int.Parse(inputParameter?.ToString()),
- Type t when t == typeof(uint) => inputParameter is null ? 0U : uint.Parse(inputParameter?.ToString()),
- Type t when t == typeof(long) => inputParameter is null ? 0L : long.Parse(inputParameter?.ToString()),
- Type t when t == typeof(ulong) => inputParameter is null ? 0UL : ulong.Parse(inputParameter?.ToString()),
- Type t when t == typeof(nint) => inputParameter is null ? 0 : nint.Parse(inputParameter?.ToString()),
- Type t when t == typeof(nuint) => inputParameter is null ? 0 : nuint.Parse(inputParameter?.ToString()),
Type t when t.IsArray => (inputParameter as Array)?.Cast
///
- public static (MethodDetails,Delegate) CreateMethodDetails(Type type, MethodInfo method, string assemblyName)
+ public static (MethodDetails?,Delegate?) CreateMethodDetails(Type type, MethodInfo method, string assemblyName)
{
var methodName = method.Name;
diff --git a/NodeFlow/Tool/ObjDynamicCreateHelper.cs b/NodeFlow/Tool/ObjDynamicCreateHelper.cs
index a30fcf2..d269cf0 100644
--- a/NodeFlow/Tool/ObjDynamicCreateHelper.cs
+++ b/NodeFlow/Tool/ObjDynamicCreateHelper.cs
@@ -1,13 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection.Emit;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using System;
-using System.Collections.Generic;
-using System.Reflection;
+using System.Reflection;
using System.Reflection.Emit;
@@ -78,7 +69,7 @@ namespace Serein.NodeFlow.Tool
// 如果类型已经缓存,直接返回缓存的类型
if (typeCache.ContainsKey(typeName))
{
- return Activator.CreateInstance(typeCache[typeName]);
+ return Activator.CreateInstance(typeCache[typeName])!;
}
// 定义动态程序集和模块
@@ -98,7 +89,7 @@ namespace Serein.NodeFlow.Tool
if (propValue is IList>) // 处理数组类型
{
- var nestedPropValue = (propValue as IList>)[0];
+ var nestedPropValue = (propValue as IList>)![0];
var nestedType = CreateObjectWithProperties(nestedPropValue, $"{propName}Element");
propType = nestedType.GetType().MakeArrayType(); // 创建数组类型
}
@@ -152,7 +143,7 @@ namespace Serein.NodeFlow.Tool
typeCache[typeName] = dynamicType;
// 创建对象实例
- return Activator.CreateInstance(dynamicType);
+ return Activator.CreateInstance(dynamicType)!;
}
// 方法 2: 递归设置对象的属性值
@@ -169,10 +160,10 @@ namespace Serein.NodeFlow.Tool
if (value is Dictionary nestedProperties)
{
// 创建嵌套对象
- var nestedObj = Activator.CreateInstance(propInfo.PropertyType);
+ var nestedObj = Activator.CreateInstance(propInfo!.PropertyType);
// 递归设置嵌套对象的值
- SetPropertyValues(nestedObj, nestedProperties);
+ SetPropertyValues(nestedObj!, nestedProperties);
// 将嵌套对象赋值给属性
propInfo.SetValue(obj, nestedObj);
@@ -180,7 +171,7 @@ namespace Serein.NodeFlow.Tool
else
{
// 直接赋值给属性
- propInfo.SetValue(obj, value);
+ propInfo!.SetValue(obj, value);
}
}
}
@@ -222,7 +213,7 @@ namespace Serein.NodeFlow.Tool
if (propValue is Dictionary nestedProperties)
{
var nestedObj = Activator.CreateInstance(propInfo.PropertyType);
- if (SetPropertyValuesWithValidation(nestedObj, nestedProperties))
+ if (nestedObj is not null && SetPropertyValuesWithValidation(nestedObj, nestedProperties))
{
propInfo.SetValue(obj, nestedObj);
}
@@ -235,22 +226,24 @@ namespace Serein.NodeFlow.Tool
{
// 获取目标类型的数组元素类型
var elementType = propInfo.PropertyType.GetElementType();
- var array = Array.CreateInstance(elementType, list.Count);
-
- for (int i = 0; i < list.Count; i++)
+ if (elementType is not null)
{
- var item = Activator.CreateInstance(elementType);
- if (SetPropertyValuesWithValidation(item, list[i]))
- {
- array.SetValue(item, i);
- }
- else
- {
- allSuccessful = false; // 赋值失败
- }
- }
+ var array = Array.CreateInstance(elementType, list.Count);
- propInfo.SetValue(obj, array);
+ for (int i = 0; i < list.Count; i++)
+ {
+ var item = Activator.CreateInstance(elementType);
+ if (item is not null && SetPropertyValuesWithValidation(item, list[i]))
+ {
+ array.SetValue(item, i);
+ }
+ else
+ {
+ allSuccessful = false; // 赋值失败
+ }
+ }
+ propInfo.SetValue(obj, array);
+ }
}
else
{
diff --git a/NodeFlow/Tool/SereinExpression/Resolver/MemberStringConditionResolver.cs b/NodeFlow/Tool/SereinExpression/Resolver/MemberStringConditionResolver.cs
index 71e7ce1..ef9493f 100644
--- a/NodeFlow/Tool/SereinExpression/Resolver/MemberStringConditionResolver.cs
+++ b/NodeFlow/Tool/SereinExpression/Resolver/MemberStringConditionResolver.cs
@@ -39,7 +39,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression.Resolver
return false;
}
- private object GetMemberValue(object? obj, string memberPath)
+ private object? GetMemberValue(object? obj, string memberPath)
{
string[] members = memberPath[1..].Split('.');
foreach (var member in members)
diff --git a/NodeFlow/Tool/SereinExpression/SereinConditionParser.cs b/NodeFlow/Tool/SereinExpression/SereinConditionParser.cs
index f5008e4..7b6ccab 100644
--- a/NodeFlow/Tool/SereinExpression/SereinConditionParser.cs
+++ b/NodeFlow/Tool/SereinExpression/SereinConditionParser.cs
@@ -29,7 +29,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
}
}
- public static SereinConditionResolver ConditionParse(object data, string expression)
+ public static SereinConditionResolver ConditionParse(object? data, string expression)
{
if (expression.StartsWith('.') || expression.StartsWith('<')) // 表达式前缀属于从上一个节点数据对象获取成员值
{
@@ -91,7 +91,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
///
/// 解析对象表达式
///
- private static SereinConditionResolver ParseObjectExpression(object data, string expression)
+ private static SereinConditionResolver ParseObjectExpression(object? data, string expression)
{
var parts = expression.Split(' ');
string operatorStr = parts[0]; // 获取操作类型
diff --git a/NodeFlow/Tool/SereinExpression/SerinExpressionEvaluator.cs b/NodeFlow/Tool/SereinExpression/SerinExpressionEvaluator.cs
index 9125247..03d0d64 100644
--- a/NodeFlow/Tool/SereinExpression/SerinExpressionEvaluator.cs
+++ b/NodeFlow/Tool/SereinExpression/SerinExpressionEvaluator.cs
@@ -41,7 +41,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
///
///
///
- public static object Evaluate(string expression, object targetObJ, out bool isChange)
+ public static object? Evaluate(string expression, object targetObJ, out bool isChange)
{
var parts = expression.Split([' '], 2);
if (parts.Length != 2)
@@ -84,7 +84,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
/// 方法名称
///
///
- private static object InvokeMethod(object target, string methodCall)
+ private static object? InvokeMethod(object target, string methodCall)
{
var methodParts = methodCall.Split(separator, StringSplitOptions.RemoveEmptyEntries);
if (methodParts.Length != 2)
@@ -98,12 +98,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
.Select(p => p.Trim())
.ToArray();
- var method = target.GetType().GetMethod(methodName);
- if (method is null)
- {
- throw new ArgumentException($"Method {methodName} not found on target.");
- }
-
+ var method = target.GetType().GetMethod(methodName) ?? throw new ArgumentException($"Method {methodName} not found on target.");
var parameterValues = method.GetParameters()
.Select((p, index) => Convert.ChangeType(parameters[index], p.ParameterType))
.ToArray();
@@ -119,15 +114,14 @@ namespace Serein.NodeFlow.Tool.SereinExpression
/// 属性路径
///
///
- private static object GetMember(object target, string memberPath)
+ private static object? GetMember(object? target, string memberPath)
{
+ if (target is null) return null;
// 分割成员路径,按 '.' 处理多级访问
var members = memberPath.Split('.');
foreach (var member in members)
{
- if (target == null) return null;
-
// 检查成员是否包含数组索引,例如 "cars[0]"
var arrayIndexStart = member.IndexOf('[');
if (arrayIndexStart != -1)
@@ -148,22 +142,22 @@ namespace Serein.NodeFlow.Tool.SereinExpression
}
// 获取数组或集合对象
- var arrayProperty = target.GetType().GetProperty(arrayName);
- if (arrayProperty != null)
+ var arrayProperty = target?.GetType().GetProperty(arrayName);
+ if (arrayProperty is null)
{
- target = arrayProperty.GetValue(target);
- }
- else
- {
- var arrayField = target.GetType().GetField(arrayName);
- if (arrayField != null)
- {
- target = arrayField.GetValue(target);
- }
- else
+ var arrayField = target?.GetType().GetField(arrayName);
+ if (arrayField is null)
{
throw new ArgumentException($"Member {arrayName} not found on target.");
}
+ else
+ {
+ target = arrayField.GetValue(target);
+ }
+ }
+ else
+ {
+ target = arrayProperty.GetValue(target);
}
// 访问数组或集合中的指定索引
@@ -191,22 +185,22 @@ namespace Serein.NodeFlow.Tool.SereinExpression
else
{
// 处理非数组情况的属性或字段
- var property = target.GetType().GetProperty(member);
- if (property != null)
+ var property = target?.GetType().GetProperty(member);
+ if (property is null)
{
- target = property.GetValue(target);
- }
- else
- {
- var field = target.GetType().GetField(member);
- if (field != null)
- {
- target = field.GetValue(target);
- }
- else
+ var field = target?.GetType().GetField(member);
+ if (field is null)
{
throw new ArgumentException($"Member {member} not found on target.");
}
+ else
+ {
+ target = field.GetValue(target);
+ }
+ }
+ else
+ {
+ target = property.GetValue(target);
}
}
}
@@ -220,7 +214,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
/// 属性路径
///
///
- private static object SetMember(object target, string assignment)
+ private static object? SetMember(object? target, string assignment)
{
var parts = assignment.Split(new[] { '=' }, 2);
if (parts.Length != 2)
@@ -238,7 +232,7 @@ namespace Serein.NodeFlow.Tool.SereinExpression
// 检查是否包含数组索引
var arrayIndexStart = member.IndexOf('[');
- if (arrayIndexStart != -1)
+ if (arrayIndexStart != -1)
{
// 解析数组名和索引
var arrayName = member.Substring(0, arrayIndexStart);
@@ -255,24 +249,24 @@ namespace Serein.NodeFlow.Tool.SereinExpression
}
// 获取数组或集合
- var arrayProperty = target.GetType().GetProperty(arrayName);
- if (arrayProperty != null)
+ var arrayProperty = target?.GetType().GetProperty(arrayName);
+ if (arrayProperty is null)
{
- target = arrayProperty.GetValue(target);
- }
- else
- {
- var arrayField = target.GetType().GetField(arrayName);
- if (arrayField != null)
- {
- target = arrayField.GetValue(target);
- }
- else
+ var arrayField = target?.GetType().GetField(arrayName);
+ if (arrayField is null)
{
throw new ArgumentException($"Member {arrayName} not found on target.");
}
+ else
+ {
+ target = arrayField.GetValue(target);
+ }
}
+ else
+ {
+ target = arrayProperty.GetValue(target);
+ }
// 获取目标数组或集合中的指定元素
if (target is Array array)
@@ -299,46 +293,47 @@ namespace Serein.NodeFlow.Tool.SereinExpression
else
{
// 处理非数组情况的属性或字段
- var property = target.GetType().GetProperty(member);
- if (property != null)
+ var property = target?.GetType().GetProperty(member);
+ if (property is null)
{
- target = property.GetValue(target);
- }
- else
- {
- var field = target.GetType().GetField(member);
- if (field != null)
- {
- target = field.GetValue(target);
- }
- else
+ var field = target?.GetType().GetField(member);
+ if (field is null)
{
throw new ArgumentException($"Member {member} not found on target.");
}
+ else
+ {
+ target = field.GetValue(target);
+ }
+ }
+ else
+ {
+ target = property.GetValue(target);
}
}
}
+ // 设置值
var lastMember = members.Last();
- var lastProperty = target.GetType().GetProperty(lastMember);
- if (lastProperty != null)
+ var lastProperty = target?.GetType().GetProperty(lastMember);
+ if (lastProperty is null)
{
- var convertedValue = Convert.ChangeType(value, lastProperty.PropertyType);
- lastProperty.SetValue(target, convertedValue);
- }
- else
- {
- var lastField = target.GetType().GetField(lastMember);
- if (lastField != null)
+ var lastField = target?.GetType().GetField(lastMember);
+ if (lastField is null)
+ {
+ throw new ArgumentException($"Member {lastMember} not found on target.");
+ }
+ else
{
var convertedValue = Convert.ChangeType(value, lastField.FieldType);
lastField.SetValue(target, convertedValue);
}
- else
- {
- throw new ArgumentException($"Member {lastMember} not found on target.");
- }
+ }
+ else
+ {
+ var convertedValue = Convert.ChangeType(value, lastProperty.PropertyType);
+ lastProperty.SetValue(target, convertedValue);
}
return target;
diff --git a/SereinFlow.sln b/SereinFlow.sln
index e4e50da..4fe2841 100644
--- a/SereinFlow.sln
+++ b/SereinFlow.sln
@@ -18,7 +18,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serein.Library.Framework",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serein.Library", "Library\Serein.Library.csproj", "{5E19D0F2-913A-4D1C-A6F8-1E1227BAA0E3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Net461DllTest", "Net461DllTest\Net461DllTest.csproj", "{E40EE629-1A38-4011-88E3-9AD036869987}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Net462DllTest", "Net462DllTest\Net462DllTest.csproj", "{E40EE629-1A38-4011-88E3-9AD036869987}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/WorkBench/App.xaml.cs b/WorkBench/App.xaml.cs
index 189ed28..63eaad1 100644
--- a/WorkBench/App.xaml.cs
+++ b/WorkBench/App.xaml.cs
@@ -12,24 +12,24 @@ namespace Serein.WorkBench
///
public partial class App : Application
{
- public class TestObject
- {
+ //public class TestObject
+ //{
- public NestedObject Data { get; set; }
+ // public NestedObject Data { get; set; }
- public class NestedObject
- {
- public int Code { get; set; }
- public int Code2 { get; set; }
+ // public class NestedObject
+ // {
+ // public int Code { get; set; }
+ // public int Code2 { get; set; }
- public string Tips { get; set; }
+ // public string Tips { get; set; }
- }
- public string ToUpper(string input)
- {
- return input.ToUpper();
- }
- }
+ // }
+ // public string ToUpper(string input)
+ // {
+ // return input.ToUpper();
+ // }
+ //}
@@ -125,7 +125,7 @@ namespace Serein.WorkBench
/// 成功加载的工程文件
///
public static SereinProjectData? FlowProjectData { get; set; }
- public static string FileDataPath = "";
+ public static string FileDataPath { get; set; } = "";
private void Application_Startup(object sender, StartupEventArgs e)
{
// 检查是否传入了参数
@@ -163,7 +163,7 @@ namespace Serein.WorkBench
string filePath;
//filePath = @"F:\临时\project\tmp\project.dnf";
//filePath = @"D:\Project\C#\TestNetFramework\Net45DllTest\Net45DllTest\bin\Debug\project.dnf";
- filePath = @"D:\Project\C#\DynamicControl\SereinFlow\Net461DllTest\bin\Debug\project.dnf";
+ filePath = @"D:\Project\C#\DynamicControl\SereinFlow\Net462DllTest\bin\Debug\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); // 读取整个文件内容
App.FlowProjectData = JsonConvert.DeserializeObject(content);
diff --git a/WorkBench/MainWindow.xaml.cs b/WorkBench/MainWindow.xaml.cs
index 5d4dccb..66a623b 100644
--- a/WorkBench/MainWindow.xaml.cs
+++ b/WorkBench/MainWindow.xaml.cs
@@ -139,15 +139,15 @@ namespace Serein.WorkBench
///
/// 组合变换容器
///
- private TransformGroup canvasTransformGroup;
+ private readonly TransformGroup canvasTransformGroup;
///
/// 缩放画布
///
- private ScaleTransform scaleTransform;
+ private readonly ScaleTransform scaleTransform;
///
/// 平移画布
///
- private TranslateTransform translateTransform;
+ private readonly TranslateTransform translateTransform;
#endregion
public MainWindow()
@@ -162,10 +162,17 @@ namespace Serein.WorkBench
InitFlowEnvironmentEvent(); // 配置环境事件
logWindow = InitConsoleOut(); // 重定向 Console 输出
- InitCanvasUI(); // 配置画布
+ canvasTransformGroup = new TransformGroup();
+ scaleTransform = new ScaleTransform();
+ translateTransform = new TranslateTransform();
+
+ canvasTransformGroup.Children.Add(scaleTransform);
+ canvasTransformGroup.Children.Add(translateTransform);
+
+ FlowChartCanvas.RenderTransform = canvasTransformGroup;
- if(App.FlowProjectData is not null)
+ if (App.FlowProjectData is not null)
{
FlowEnvironment.LoadProject(App.FlowProjectData, App.FileDataPath); // 加载项目
}
@@ -198,17 +205,7 @@ namespace Serein.WorkBench
- private void InitCanvasUI()
- {
- canvasTransformGroup = new TransformGroup();
- scaleTransform = new ScaleTransform();
- translateTransform = new TranslateTransform();
-
- canvasTransformGroup.Children.Add(scaleTransform);
- canvasTransformGroup.Children.Add(translateTransform);
- FlowChartCanvas.RenderTransform = canvasTransformGroup;
- }
private LogWindow InitConsoleOut()
{
@@ -243,7 +240,7 @@ namespace Serein.WorkBench
}
var canvasData = project.Basic.Canvas;
- if (canvasData != null)
+ if (canvasData is not null)
{
scaleTransform.ScaleX = 1;
scaleTransform.ScaleY = 1;
@@ -355,9 +352,9 @@ namespace Serein.WorkBench
End = toNode,
Type = connectionType
};
- if (toNode is FlipflopNodeControl flipflopControl) // 某个节点连接到了触发器,尝试从全局触发器视图中移除该触发器
+ if (toNode is FlipflopNodeControl flipflopControl
+ && flipflopControl?.ViewModel?.Node is NodeModelBase nodeModel) // 某个节点连接到了触发器,尝试从全局触发器视图中移除该触发器
{
- var nodeModel = flipflopControl?.ViewModel?.Node;
NodeTreeViewer.RemoteGlobalFlipFlop(nodeModel); // 从全局触发器树树视图中移除
}
@@ -556,7 +553,7 @@ namespace Serein.WorkBench
}
else
{
- if (ViewObjectViewer.MonitorKey.Equals(monitorKey)) // 相同对象
+ if (monitorKey.Equals(ViewObjectViewer.MonitorKey)) // 相同对象
{
ViewObjectViewer.RefreshObjectTree(eventArgs.NewData); // 刷新
}
@@ -704,7 +701,7 @@ namespace Serein.WorkBench
/// 抖动第一下偏移量
/// 减弱幅度(小于等于power,大于0)
/// 持续系数(大于0),越大时间越长,
- private static void ElasticAnimation(NodeControlBase? nodeControl, TranslateTransform translate, int power, int range = 1, double speed = 1)
+ private static void ElasticAnimation(NodeControlBase nodeControl, TranslateTransform translate, int power, int range = 1, double speed = 1)
{
DoubleAnimationUsingKeyFrames animation1 = new DoubleAnimationUsingKeyFrames();
for (int i = power, j = 1; i >= 0; i -= range)
@@ -883,10 +880,10 @@ namespace Serein.WorkBench
/// 任何情景下都尽量避免直接操作 ViewModel 中的 NodeModel 节点,而是应该调用 FlowEnvironment 提供接口进行操作。 因为 Workbench 应该更加关注UI视觉效果,而非直接干扰流程环境运行的逻辑。 之所以暴露 NodeModel 属性,因为有些场景下不可避免的需要直接获取节点的属性。
private void ConfigureContextMenu(NodeControlBase nodeControl)
{
+
var contextMenu = new ContextMenu();
- // var nodeModel = nodeControl.ViewModel.Node;
-
+
if (nodeControl.ViewModel.Node?.MethodDetails?.ReturnType is Type returnType && returnType != typeof(void))
{
contextMenu.Items.Add(CreateMenuItem("查看返回类型", (s, e) =>
@@ -894,7 +891,7 @@ namespace Serein.WorkBench
DisplayReturnTypeTreeViewer(returnType);
}));
}
- var nodeGuid = nodeControl?.ViewModel?.Node?.Guid;
+ var nodeGuid = nodeControl.ViewModel?.Node?.Guid;
#region 右键菜单功能 - 中断
@@ -923,10 +920,10 @@ namespace Serein.WorkBench
contextMenu.Items.Add(CreateMenuItem("设为起点", (s, e) => FlowEnvironment.SetStartNode(nodeGuid)));
contextMenu.Items.Add(CreateMenuItem("删除", (s, e) => FlowEnvironment.RemoteNode(nodeGuid)));
- contextMenu.Items.Add(CreateMenuItem("添加 真分支", (s, e) => StartConnection(nodeControl, ConnectionType.IsSucceed)));
- contextMenu.Items.Add(CreateMenuItem("添加 假分支", (s, e) => StartConnection(nodeControl, ConnectionType.IsFail)));
- contextMenu.Items.Add(CreateMenuItem("添加 异常分支", (s, e) => StartConnection(nodeControl, ConnectionType.IsError)));
- contextMenu.Items.Add(CreateMenuItem("添加 上游分支", (s, e) => StartConnection(nodeControl, ConnectionType.Upstream)));
+ contextMenu.Items.Add(CreateMenuItem("添加 真分支", (s, e) => StartConnection((NodeControlBase)s, ConnectionType.IsSucceed)));
+ contextMenu.Items.Add(CreateMenuItem("添加 假分支", (s, e) => StartConnection((NodeControlBase)s, ConnectionType.IsFail)));
+ contextMenu.Items.Add(CreateMenuItem("添加 异常分支", (s, e) => StartConnection((NodeControlBase)s, ConnectionType.IsError)));
+ contextMenu.Items.Add(CreateMenuItem("添加 上游分支", (s, e) => StartConnection((NodeControlBase)s, ConnectionType.Upstream)));
@@ -976,6 +973,10 @@ namespace Serein.WorkBench
{
var contextMenu = new ContextMenu();
contextMenu.Items.Add(CreateMenuItem("删除连线", (s, e) => DeleteConnection(connection)));
+ if (connection.ArrowPath is null || connection.BezierPath is null)
+ {
+ return;
+ }
connection.ArrowPath.ContextMenu = contextMenu;
connection.BezierPath.ContextMenu = contextMenu;
}
@@ -1198,8 +1199,8 @@ namespace Serein.WorkBench
// 准备放置条件表达式控件
if (nodeControl.ViewModel.Node.ControlType == NodeControlType.ExpCondition)
{
- ConditionRegionControl conditionRegion = GetParentOfType(hitElement);
- if (conditionRegion != null)
+ ConditionRegionControl? conditionRegion = GetParentOfType(hitElement);
+ if (conditionRegion is not null)
{
TryPlaceNodeInRegion(conditionRegion, nodeControl);
//// 如果存在条件区域容器
@@ -1222,8 +1223,8 @@ namespace Serein.WorkBench
// 准备放置条件表达式控件
if (nodeControl.ViewModel.Node.ControlType == NodeControlType.ExpCondition)
{
- ConditionRegionControl conditionRegion = regionControl as ConditionRegionControl;
- if (conditionRegion != null)
+ ConditionRegionControl? conditionRegion = regionControl as ConditionRegionControl;
+ if (conditionRegion is not null)
{
// 如果存在条件区域容器
conditionRegion.AddCondition(nodeControl);
@@ -1365,14 +1366,17 @@ namespace Serein.WorkBench
}
private void ChangeViewerObjOfNode(NodeControlBase nodeControl)
{
- var node = nodeControl?.ViewModel?.Node;
+ var node = nodeControl.ViewModel.Node;
//if (node is not null && (node.MethodDetails is null || node.MethodDetails.ReturnType != typeof(void))
- if (node is not null && node?.MethodDetails?.ReturnType != typeof(void))
+ if (node is not null && node.MethodDetails?.ReturnType != typeof(void))
{
var key = node.Guid;
var instance = node.GetFlowData();
- ViewObjectViewer.LoadObjectInformation(key, instance);
- ChangeViewerObj(key, instance);
+ if(instance is not null)
+ {
+ ViewObjectViewer.LoadObjectInformation(key, instance);
+ ChangeViewerObj(key, instance);
+ }
}
}
public void ChangeViewerObj(string key, object instance)
@@ -1768,64 +1772,6 @@ namespace Serein.WorkBench
}
e.Handled = true; // 防止事件传播影响其他控件
- return;
- // 如果正在选取状态,再次点击画布时自动确定选取范围,否则进入选取状态
- if (IsSelectControl)
- {
- IsSelectControl = false;
- // 释放鼠标捕获
- FlowChartCanvas.ReleaseMouseCapture();
-
- // 隐藏选取矩形(如果需要保持选取状态显示,可以删除此行)
- SelectionRectangle.Visibility = Visibility.Collapsed;
-
- // 处理选取区域内的元素(例如,获取选取范围内的控件)
- Rect selectionArea = new Rect(Canvas.GetLeft(SelectionRectangle),
- Canvas.GetTop(SelectionRectangle),
- SelectionRectangle.Width,
- SelectionRectangle.Height);
-
-
- // 在此处处理选取的逻辑
- foreach (UIElement element in FlowChartCanvas.Children)
- {
- Rect elementBounds = new Rect(Canvas.GetLeft(element), Canvas.GetTop(element),
- element.RenderSize.Width, element.RenderSize.Height);
-
- if (selectionArea.Contains(elementBounds))
- {
- // 选中元素,执行相应操作
- if (element is NodeControlBase control)
- {
- selectNodeControls.Add(control);
- }
- }
- }
- SelectedNode();// 选择之后需要执行的操作
- }
- else
- {
- // 进入选取状态
- IsSelectControl = true;
-
- // 开始选取时,记录鼠标起始点
- startSelectControolPoint = e.GetPosition(FlowChartCanvas);
-
- // 初始化选取矩形的位置和大小
- Canvas.SetLeft(SelectionRectangle, startSelectControolPoint.X);
- Canvas.SetTop(SelectionRectangle, startSelectControolPoint.Y);
- SelectionRectangle.Width = 0;
- SelectionRectangle.Height = 0;
-
- // 显示选取矩形
- SelectionRectangle.Visibility = Visibility.Visible;
- SelectionRectangle.ContextMenu ??= ConfiguerSelectionRectangle();
-
- // 捕获鼠标,以便在鼠标移动到Canvas外部时仍能处理事件
- FlowChartCanvas.CaptureMouse();
-
- }
- e.Handled = true; // 防止事件传播影响其他控件
}
///
@@ -2323,13 +2269,13 @@ namespace Serein.WorkBench
///
///
///
- private static T GetParentOfType(DependencyObject element) where T : DependencyObject
+ private static T? GetParentOfType(DependencyObject element) where T : DependencyObject
{
while (element != null)
{
- if (element is T)
+ if (element is T e)
{
- return element as T;
+ return e;
}
element = VisualTreeHelper.GetParent(element);
}
@@ -2342,9 +2288,9 @@ namespace Serein.WorkBench
private void JudgmentFlipFlopNode(NodeControlBase nodeControl)
{
- if (nodeControl is FlipflopNodeControl flipflopControl) // 判断是否为触发器
+ if (nodeControl is FlipflopNodeControl flipflopControl
+ && flipflopControl?.ViewModel?.Node is NodeModelBase nodeModel) // 判断是否为触发器
{
- var nodeModel = flipflopControl?.ViewModel?.Node;
int count = 0;
foreach (var ct in NodeStaticConfig.ConnectionTypes)
{
@@ -2473,13 +2419,18 @@ namespace Serein.WorkBench
node.Position = new Position(positionRelativeToParent.X, positionRelativeToParent.Y);
}
}
- var isPass = SaveContentToFile(out string savePath, out Action? savaProjectFile);
- if(!isPass)
+ if (!SaveContentToFile(out string savePath, out Action? savaProjectFile))
{
+ Console.WriteLine("保存项目DLL时返回了意外的文件保存路径");
return;
}
- string librarySavePath = System.IO.Path.GetDirectoryName(savePath);
+ string? librarySavePath = System.IO.Path.GetDirectoryName(savePath);
+ if (string.IsNullOrEmpty(librarySavePath))
+ {
+ Console.WriteLine("保存项目DLL时返回了意外的文件保存路径");
+ return;
+ }
Console.WriteLine(savePath);
for (int index = 0; index < projectData.Librarys.Length; index++)
{
@@ -2578,17 +2529,17 @@ namespace Serein.WorkBench
///
private void ButtonTestExpObj_Click(object sender, RoutedEventArgs e)
{
- string jsonString =
- """
- {
- "Name": "张三",
- "Age": 24,
- "Address": {
- "City": "北京",
- "PostalCode": "10000"
- }
- }
- """;
+ //string jsonString =
+ //"""
+ //{
+ // "Name": "张三",
+ // "Age": 24,
+ // "Address": {
+ // "City": "北京",
+ // "PostalCode": "10000"
+ // }
+ //}
+ //""";
var externalData = new Dictionary
{
@@ -2615,12 +2566,12 @@ namespace Serein.WorkBench
Console.WriteLine("赋值过程中有错误,请检查属性名和类型!");
}
- ObjDynamicCreateHelper.PrintObjectProperties(result);
+ ObjDynamicCreateHelper.PrintObjectProperties(result!);
Console.WriteLine( );
var exp = "@set .Addresses[1].Street = qwq";
- var data = SerinExpressionEvaluator.Evaluate(exp, result, out bool isChange);
+ var data = SerinExpressionEvaluator.Evaluate(exp, result!, out bool isChange);
exp = "@get .Addresses[1].Street";
- data = SerinExpressionEvaluator.Evaluate(exp,result, out isChange);
+ data = SerinExpressionEvaluator.Evaluate(exp,result!, out isChange);
Console.WriteLine($"{exp} => {data}");
}
@@ -2681,22 +2632,29 @@ namespace Serein.WorkBench
canvas.Dispatcher.InvokeAsync(() =>
{
- if (connection is not null && connection.BezierPath is null)
+ if (connection is null)
+ {
+ return;
+ }
+
+ if (connection.BezierPath is null)
{
connection.BezierPath = new System.Windows.Shapes.Path { Stroke = BezierLineDrawer.GetLineColor(connection.Type), StrokeThickness = 1 };
//Canvas.SetZIndex(connection.BezierPath, -1);
canvas.Children.Add(connection.BezierPath);
}
- if (connection is not null && connection.ArrowPath is null)
+ if (connection.ArrowPath is null)
{
connection.ArrowPath = new System.Windows.Shapes.Path { Stroke = BezierLineDrawer.GetLineColor(connection.Type), Fill = BezierLineDrawer.GetLineColor(connection.Type), StrokeThickness = 1 };
//Canvas.SetZIndex(connection.ArrowPath, -1);
canvas.Children.Add(connection.ArrowPath);
}
+
BezierLineDrawer.UpdateBezierLine(canvas, connection.Start, connection.End, connection.BezierPath, connection.ArrowPath);
isUpdating = false;
+
});
}
@@ -2746,10 +2704,10 @@ namespace Serein.WorkBench
public class Connection
{
public ConnectionType Type { get; set; }
- public Canvas Canvas { get; set; }// 贝塞尔曲线所在画布
+ public Canvas? Canvas { get; set; }// 贝塞尔曲线所在画布
- public System.Windows.Shapes.Path BezierPath { get; set; }// 贝塞尔曲线路径
- public System.Windows.Shapes.Path ArrowPath { get; set; } // 箭头路径
+ public System.Windows.Shapes.Path? BezierPath { get; set; }// 贝塞尔曲线路径
+ public System.Windows.Shapes.Path? ArrowPath { get; set; } // 箭头路径
public required NodeControlBase Start { get; set; } // 起始
public required NodeControlBase End { get; set; } // 结束
@@ -2757,8 +2715,11 @@ namespace Serein.WorkBench
public void RemoveFromCanvas()
{
- Canvas.Children.Remove(BezierPath); // 移除线
- Canvas.Children.Remove(ArrowPath); // 移除线
+ if(Canvas != null)
+ {
+ Canvas.Children.Remove(BezierPath); // 移除线
+ Canvas.Children.Remove(ArrowPath); // 移除线
+ }
}
///
@@ -2766,6 +2727,10 @@ namespace Serein.WorkBench
///
public void Refresh()
{
+ if(Canvas is null || BezierPath is null || ArrowPath is null)
+ {
+ return;
+ }
BezierLineDrawer.UpdateBezierLine(Canvas, Start, End, BezierPath, ArrowPath);
}
}
diff --git a/WorkBench/Node/View/ConditionRegionControl.xaml.cs b/WorkBench/Node/View/ConditionRegionControl.xaml.cs
index 80339e7..e1a650a 100644
--- a/WorkBench/Node/View/ConditionRegionControl.xaml.cs
+++ b/WorkBench/Node/View/ConditionRegionControl.xaml.cs
@@ -12,7 +12,6 @@ namespace Serein.WorkBench.Node.View
///
public partial class ConditionRegionControl : NodeControlBase
{
- private Point _dragStartPoint;
public ConditionRegionControl() : base()
{
diff --git a/WorkBench/Themes/NodeTreeItemViewControl.xaml.cs b/WorkBench/Themes/NodeTreeItemViewControl.xaml.cs
index d5b5a9e..c35edad 100644
--- a/WorkBench/Themes/NodeTreeItemViewControl.xaml.cs
+++ b/WorkBench/Themes/NodeTreeItemViewControl.xaml.cs
@@ -74,7 +74,7 @@ namespace Serein.WorkBench.Themes
{ConnectionType.IsError, []},
}
};
- string itemName = rootNodeModel?.MethodDetails?.MethodTips;
+ string? itemName = rootNodeModel.MethodDetails?.MethodTips;
if (string.IsNullOrEmpty(itemName))
{
itemName = rootNodeModel.ControlType.ToString();
@@ -141,10 +141,10 @@ namespace Serein.WorkBench.Themes
RootNode = child,
ChildNodes = child.SuccessorNodes,
};
- string itemName = child?.MethodDetails?.MethodTips;
+ string? itemName = child?.MethodDetails?.MethodTips;
if (string.IsNullOrEmpty(itemName))
{
- itemName = child.ControlType.ToString();
+ itemName = child?.ControlType.ToString();
}
TreeViewItem treeViewItem = new TreeViewItem
{
@@ -204,10 +204,10 @@ namespace Serein.WorkBench.Themes
ChildNodes = childNodeModel.SuccessorNodes,
};
- string itemName = childNodeModel?.MethodDetails?.MethodTips;
+ string? itemName = childNodeModel?.MethodDetails?.MethodTips;
if (string.IsNullOrEmpty(itemName))
{
- itemName = childNodeModel.ControlType.ToString();
+ itemName = childNodeModel?.ControlType.ToString();
}
TreeViewItem treeViewItem = new TreeViewItem
{
diff --git a/WorkBench/Themes/NodeTreeViewControl.xaml.cs b/WorkBench/Themes/NodeTreeViewControl.xaml.cs
index 70f4a0e..39c7cb6 100644
--- a/WorkBench/Themes/NodeTreeViewControl.xaml.cs
+++ b/WorkBench/Themes/NodeTreeViewControl.xaml.cs
@@ -22,7 +22,6 @@ namespace Serein.WorkBench.Themes
///
public partial class NodeTreeViewControl : UserControl
{
- private IFlowEnvironment FlowEnvironment { get; set; }
public NodeTreeViewControl()
{
InitializeComponent();
diff --git a/WorkBench/Themes/ObjectViewerControl.xaml.cs b/WorkBench/Themes/ObjectViewerControl.xaml.cs
index 65390a2..cb292d4 100644
--- a/WorkBench/Themes/ObjectViewerControl.xaml.cs
+++ b/WorkBench/Themes/ObjectViewerControl.xaml.cs
@@ -32,7 +32,7 @@ namespace Serein.WorkBench.Themes
///
/// 属性名称
///
- public string Name { get; set; }
+ public string? Name { get; set; }
///
/// 属性类型
///
@@ -40,15 +40,15 @@ namespace Serein.WorkBench.Themes
///
/// 数据类型
///
- public Type DataType { get; set; }
+ public Type? DataType { get; set; }
///
/// 数据
///
- public object DataValue { get; set; }
+ public object? DataValue { get; set; }
///
/// 数据路径
///
- public string DataPath { get; set; }
+ public string DataPath { get; set; } = string.Empty;
}
@@ -80,24 +80,24 @@ namespace Serein.WorkBench.Themes
///
/// 运行环境
///
- public IFlowEnvironment FlowEnvironment { get; set; }
+ public IFlowEnvironment? FlowEnvironment { get; set; }
///
/// 监视对象的键
///
- public string MonitorKey { get => monitorKey; }
+ public string? MonitorKey { get => monitorKey; }
///
/// 正在监视的对象
///
- public object MonitorObj { get => monitorObj; }
+ public object? MonitorObj { get => monitorObj; }
///
/// 监视表达式
///
- public string MonitorExpression { get => ExpressionTextBox.Text.ToString(); }
+ public string? MonitorExpression { get => ExpressionTextBox.Text.ToString(); }
- private string monitorKey;
- private object monitorObj;
+ private string? monitorKey;
+ private object? monitorObj;
// 用于存储当前展开的节点路径
private HashSet expandedNodePaths = new HashSet();
@@ -133,7 +133,7 @@ namespace Serein.WorkBench.Themes
///
private void UpMonitorExpressionButton_Click(object sender, RoutedEventArgs e)
{
- if (FlowEnvironment.AddInterruptExpression(monitorKey, MonitorExpression)) // 对象预览器尝试添加中断表达式
+ if (FlowEnvironment is not null && FlowEnvironment.AddInterruptExpression(monitorKey, MonitorExpression)) // 对象预览器尝试添加中断表达式
{
if (string.IsNullOrEmpty(MonitorExpression))
{
@@ -146,7 +146,7 @@ namespace Serein.WorkBench.Themes
}
}
- private TreeViewItem? LoadTree(object obj)
+ private TreeViewItem? LoadTree(object? obj)
{
if (obj is null) return null;
var objectType = obj.GetType();
@@ -178,7 +178,7 @@ namespace Serein.WorkBench.Themes
///
/// 刷新对象属性树
///
- public void RefreshObjectTree(object obj)
+ public void RefreshObjectTree(object? obj)
{
monitorObj = obj;
var rootNode = LoadTree(obj);
@@ -222,14 +222,20 @@ namespace Serein.WorkBench.Themes
{
if (item.Tag is FlowDataDetails flowDataDetails) // FlowDataDetails flowDataDetails object obj
{
- if (flowDataDetails.ItemType == TreeItemType.Item || item.Items.Count == 0)
+ if (flowDataDetails.ItemType != TreeItemType.Item && item.Items.Count != 0)
{
- // 记录当前节点的路径
- var path = flowDataDetails.DataPath;
- expandedNodePaths.Add(path);
- AddMembersToTreeNode(item, flowDataDetails.DataValue, flowDataDetails.DataType);
+ return;
}
-
+ if(flowDataDetails.DataValue is null || flowDataDetails.DataType is null)
+ {
+ return;
+ }
+
+ // 记录当前节点的路径
+ var path = flowDataDetails.DataPath;
+ expandedNodePaths.Add(path);
+ AddMembersToTreeNode(item, flowDataDetails.DataValue, flowDataDetails.DataType);
+
}
}
}
@@ -276,8 +282,8 @@ namespace Serein.WorkBench.Themes
continue;
}
- TreeViewItem memberNode = ConfigureTreeViewItem(obj, member); // 根据对象成员生成节点对象
- if (memberNode != null)
+ TreeViewItem? memberNode = ConfigureTreeViewItem(obj, member); // 根据对象成员生成节点对象
+ if (memberNode is not null)
{
treeViewNode.Items.Add(memberNode); // 添加到当前节点
@@ -305,7 +311,7 @@ namespace Serein.WorkBench.Themes
///
///
///
- private TreeViewItem ConfigureTreeViewItem(object obj, MemberInfo member)
+ private TreeViewItem? ConfigureTreeViewItem(object obj, MemberInfo member)
{
if (obj == null)
{
@@ -353,7 +359,7 @@ namespace Serein.WorkBench.Themes
else
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
- string propertyValue = GetPropertyValue(obj, property, out object value);
+ string propertyValue = GetPropertyValue(obj, property, out object? value);
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.Property,
@@ -417,7 +423,7 @@ namespace Serein.WorkBench.Themes
else
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
- string fieldValue = GetFieldValue(obj, field, out object value);
+ string fieldValue = GetFieldValue(obj, field, out object? value);
memberNode.Tag = new FlowDataDetails
{
@@ -454,7 +460,7 @@ namespace Serein.WorkBench.Themes
///
///
///
- private string GetPropertyValue(object obj, PropertyInfo property,out object value)
+ private string GetPropertyValue(object obj, PropertyInfo property,out object? value)
{
try
{
@@ -482,7 +488,7 @@ namespace Serein.WorkBench.Themes
///
///
///
- private string GetFieldValue(object obj, FieldInfo field, out object value)
+ private string GetFieldValue(object obj, FieldInfo field, out object? value)
{
try
{
diff --git a/WorkBench/Themes/TypeViewerWindow.xaml.cs b/WorkBench/Themes/TypeViewerWindow.xaml.cs
index ceb0fcf..f8e18c3 100644
--- a/WorkBench/Themes/TypeViewerWindow.xaml.cs
+++ b/WorkBench/Themes/TypeViewerWindow.xaml.cs
@@ -227,10 +227,10 @@ namespace Serein.WorkBench.Themes
///
/// 目标节点
/// 父节点
- private TreeViewItem GetParentTreeViewItem(TreeViewItem node)
+ private TreeViewItem? GetParentTreeViewItem(TreeViewItem node)
{
DependencyObject parent = VisualTreeHelper.GetParent(node);
- while (parent != null && !(parent is TreeViewItem))
+ while (parent != null && parent is not TreeViewItem)
{
parent = VisualTreeHelper.GetParent(parent);
}
diff --git a/WorkBench/Tool/Converters/InvertableBooleanToVisibilityConverter.cs b/WorkBench/Tool/Converters/InvertableBooleanToVisibilityConverter.cs
index 39b5d18..3f85c37 100644
--- a/WorkBench/Tool/Converters/InvertableBooleanToVisibilityConverter.cs
+++ b/WorkBench/Tool/Converters/InvertableBooleanToVisibilityConverter.cs
@@ -29,7 +29,7 @@ namespace Serein.WorkBench.Tool.Converters
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
- public object ConvertBack(object value, Type targetType,
+ public object? ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;