diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..cb53e99
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# CA1416: 验证平台兼容性
+dotnet_diagnostic.CA1416.severity = silent
diff --git a/ATS.sln b/ATS.sln
new file mode 100644
index 0000000..349e881
--- /dev/null
+++ b/ATS.sln
@@ -0,0 +1,66 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36221.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ATS", "ATS\ATS.csproj", "{000A2999-6535-43D3-94DA-EE372D19702F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{AEA71207-A57F-424A-9AA0-9AC9A4B681F1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceCommand", "DeviceCommand\DeviceCommand.csproj", "{13E7EF22-4595-D29C-1E97-91B321696C07}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Command", "Command\Command.csproj", "{59379C4C-4B0B-43FE-A56E-9532BAD20F9C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TOSUNCAN", "TOSUNCAN\TOSUNCAN.csproj", "{7810B83D-B705-B118-EA4E-CAD8F65E25F7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ATS_DBContext", "ATS_DBContext\ATS_DBContext.csproj", "{D1356D14-DC7D-42B1-BDF2-EC37D09562E0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "加密狗", "加密狗\加密狗.csproj", "{E4D76F6D-39C5-4F4F-B81A-31D9828A8CC6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {000A2999-6535-43D3-94DA-EE372D19702F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {000A2999-6535-43D3-94DA-EE372D19702F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {000A2999-6535-43D3-94DA-EE372D19702F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {000A2999-6535-43D3-94DA-EE372D19702F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AEA71207-A57F-424A-9AA0-9AC9A4B681F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEA71207-A57F-424A-9AA0-9AC9A4B681F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AEA71207-A57F-424A-9AA0-9AC9A4B681F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AEA71207-A57F-424A-9AA0-9AC9A4B681F1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {13E7EF22-4595-D29C-1E97-91B321696C07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {13E7EF22-4595-D29C-1E97-91B321696C07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {13E7EF22-4595-D29C-1E97-91B321696C07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {13E7EF22-4595-D29C-1E97-91B321696C07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {59379C4C-4B0B-43FE-A56E-9532BAD20F9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {59379C4C-4B0B-43FE-A56E-9532BAD20F9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {59379C4C-4B0B-43FE-A56E-9532BAD20F9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {59379C4C-4B0B-43FE-A56E-9532BAD20F9C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7810B83D-B705-B118-EA4E-CAD8F65E25F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7810B83D-B705-B118-EA4E-CAD8F65E25F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7810B83D-B705-B118-EA4E-CAD8F65E25F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7810B83D-B705-B118-EA4E-CAD8F65E25F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1356D14-DC7D-42B1-BDF2-EC37D09562E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1356D14-DC7D-42B1-BDF2-EC37D09562E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1356D14-DC7D-42B1-BDF2-EC37D09562E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1356D14-DC7D-42B1-BDF2-EC37D09562E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4D76F6D-39C5-4F4F-B81A-31D9828A8CC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4D76F6D-39C5-4F4F-B81A-31D9828A8CC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4D76F6D-39C5-4F4F-B81A-31D9828A8CC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4D76F6D-39C5-4F4F-B81A-31D9828A8CC6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F2C112EA-AA28-490A-B794-5E0D540A92C9}
+ EndGlobalSection
+EndGlobal
diff --git a/ATS/ATS.csproj b/ATS/ATS.csproj
new file mode 100644
index 0000000..74fce97
--- /dev/null
+++ b/ATS/ATS.csproj
@@ -0,0 +1,44 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ enable
+ true
+ preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\TOSUNCAN\Interop.TSMasterAPI.dll
+
+
+
+
diff --git a/ATS/App.xaml b/ATS/App.xaml
new file mode 100644
index 0000000..2d2c712
--- /dev/null
+++ b/ATS/App.xaml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pack://application:,,,/BVC;component/字体/MiSans-Normal.ttf#misans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ATS/App.xaml.cs b/ATS/App.xaml.cs
new file mode 100644
index 0000000..fcaad57
--- /dev/null
+++ b/ATS/App.xaml.cs
@@ -0,0 +1,25 @@
+using ATS.Tools;
+using System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace ATS
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ if (SecurityDongle.Verify() <= 0)
+ {
+ MessageBox.Show("加密狗到期或检测失败!\n");
+ App.Current.Shutdown();
+ return;
+ }
+ base.OnStartup(e);
+ }
+ }
+
+}
diff --git a/ATS/AssemblyInfo.cs b/ATS/AssemblyInfo.cs
new file mode 100644
index 0000000..b0ec827
--- /dev/null
+++ b/ATS/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/ATS/Converters/BoolInverseConverter.cs b/ATS/Converters/BoolInverseConverter.cs
new file mode 100644
index 0000000..05cdccf
--- /dev/null
+++ b/ATS/Converters/BoolInverseConverter.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class BoolInverseConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value != null)
+ {
+ return value is bool b ? !b : value;
+ }
+ return false;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value is bool b ? !b : value;
+ }
+ }
+}
diff --git a/ATS/Converters/BooleanToVisibilityConverter.cs b/ATS/Converters/BooleanToVisibilityConverter.cs
new file mode 100644
index 0000000..a93f291
--- /dev/null
+++ b/ATS/Converters/BooleanToVisibilityConverter.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class BooleanToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is bool boolValue)
+ {
+ // 处理反转逻辑
+ if (parameter?.ToString() == "Inverse")
+ {
+ boolValue = !boolValue;
+ }
+ return boolValue ? Visibility.Visible : Visibility.Collapsed;
+ }
+ return Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/DeviceNameConverter.cs b/ATS/Converters/DeviceNameConverter.cs
new file mode 100644
index 0000000..1f8087e
--- /dev/null
+++ b/ATS/Converters/DeviceNameConverter.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class DeviceNameConverter : IValueConverter
+ {
+ private readonly string[] specialName = { "奇偶" };
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is string name)
+ {
+ if (specialName.Contains(name))
+ {
+ if (parameter?.ToString() == "Inverse")
+ {
+ return Visibility.Visible;
+ }
+ else if (parameter?.ToString() == "Items")
+ {
+ switch (name)
+ {
+ case "奇偶":
+ return new List { "无", "奇", "偶" };
+ }
+ }
+ return Visibility.Collapsed;
+ }
+ }
+ if (parameter?.ToString() == "Inverse")
+ {
+ return Visibility.Collapsed;
+ }
+ return Visibility.Visible;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/DeviceSettingWindowConverter.cs b/ATS/Converters/DeviceSettingWindowConverter.cs
new file mode 100644
index 0000000..8b80a76
--- /dev/null
+++ b/ATS/Converters/DeviceSettingWindowConverter.cs
@@ -0,0 +1,33 @@
+using ATS.Models;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class DeviceSettingWindowConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(parameter?.ToString()== "ToList")
+ {
+ return JsonConvert.DeserializeObject>(value.ToString());
+ }
+ else
+ {
+ return value;
+ }
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/EnumValueConverter.cs b/ATS/Converters/EnumValueConverter.cs
new file mode 100644
index 0000000..9bcef69
--- /dev/null
+++ b/ATS/Converters/EnumValueConverter.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class EnumValueConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ // 验证输入参数
+ if (values.Length < 2 || values[0] == null || values[1] == null)
+ {
+ return null;
+ }
+
+ try
+ {
+ // 获取枚举类型
+ Type enumType = values[0] as Type;
+ if (enumType == null || !enumType.IsEnum)
+ {
+ return null;
+ }
+
+ // 获取数值
+ object value = values[1];
+
+ // 确保数值类型匹配枚举的底层类型
+ Type underlyingType = Enum.GetUnderlyingType(enumType);
+ object convertedValue;
+
+ try
+ {
+ convertedValue = System.Convert.ChangeType(value, underlyingType);
+ }
+ catch
+ {
+ // 如果转换失败,尝试直接使用原始值
+ convertedValue = value;
+ }
+
+ // 将数值转换为枚举值
+ return Enum.ToObject(enumType, convertedValue);
+ }
+ catch
+ {
+ // 发生任何异常时返回null
+ return null;
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ if (value == null)
+ {
+ return [null, null];
+ }
+
+ try
+ {
+ // 获取枚举值的底层数值
+ Type enumType = value.GetType();
+ if (!enumType.IsEnum)
+ {
+ return [null, null];
+ }
+
+ Type underlyingType = Enum.GetUnderlyingType(enumType);
+ object numericValue = System.Convert.ChangeType(value, underlyingType);
+
+ // 返回枚举类型和对应的数值
+ return [enumType, numericValue];
+ }
+ catch
+ {
+ return [null, null];
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ATS/Converters/EnumValuesConverter.cs b/ATS/Converters/EnumValuesConverter.cs
new file mode 100644
index 0000000..51b5807
--- /dev/null
+++ b/ATS/Converters/EnumValuesConverter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class EnumValuesConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Type type && type.IsEnum)
+ {
+ return Enum.GetValues(type);
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ATS/Converters/FilteredParametersConverter.cs b/ATS/Converters/FilteredParametersConverter.cs
new file mode 100644
index 0000000..531218c
--- /dev/null
+++ b/ATS/Converters/FilteredParametersConverter.cs
@@ -0,0 +1,76 @@
+using ATS.Models;
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class FilteredParametersConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values.Length < 2 || values[0] == null || values[1] == null)
+ return null;
+
+ Type currentParamType = values[0] as Type;
+ var allParameters = values[1] as System.Collections.IEnumerable;
+
+ if (currentParamType == null || allParameters == null)
+ return allParameters;
+
+ // 过滤出类型匹配的参数
+ return allParameters.Cast()
+ .Where(p => IsTypeMatch(currentParamType, p.Type))
+ .ToList();
+ }
+
+ private bool IsTypeMatch(Type currentType, Type candidateType)
+ {
+ if (candidateType == null) return false;
+
+ // 如果候选参数类型是 object,则匹配所有类型
+ if (candidateType == typeof(object)) return true;
+
+ // 如果当前参数类型是 object,则匹配所有类型
+ if (currentType == typeof(object)) return true;
+
+ // 如果类型完全相同,则匹配
+ if (candidateType == currentType) return true;
+
+ // 处理数值类型的兼容性
+ if (IsNumericType(currentType) && IsNumericType(candidateType))
+ return true;
+
+ return false;
+ }
+
+ private bool IsNumericType(Type type)
+ {
+ if (type == null) return false;
+
+ switch (Type.GetTypeCode(type))
+ {
+ case TypeCode.Byte:
+ case TypeCode.SByte:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ case TypeCode.UInt64:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ case TypeCode.Int64:
+ case TypeCode.Decimal:
+ case TypeCode.Double:
+ case TypeCode.Single:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ATS/Converters/GuidToParameterNameConverter.cs b/ATS/Converters/GuidToParameterNameConverter.cs
new file mode 100644
index 0000000..89a1b1d
--- /dev/null
+++ b/ATS/Converters/GuidToParameterNameConverter.cs
@@ -0,0 +1,29 @@
+using ATS.Windows;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class GuidToParameterNameConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is Guid id)
+ {
+ var para = MainWindow.Instance.Program.Parameters.FirstOrDefault(x => x.ID == id);
+ if(para != null) return para.Name;
+ }
+ return "";
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/HexConverter.cs b/ATS/Converters/HexConverter.cs
new file mode 100644
index 0000000..78d7512
--- /dev/null
+++ b/ATS/Converters/HexConverter.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class HexConverter : IValueConverter
+ {
+ // 显示时:int → hex 字符串
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is int i)
+ return $"0x{i:X}"; // 例如 255 → 0xFF
+ return "0x0";
+ }
+
+ // 用户输入时:hex 字符串 → int
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var str = value?.ToString()?.Trim();
+
+ if (string.IsNullOrWhiteSpace(str))
+ return 0;
+
+ if (str.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
+ str = str.Substring(2);
+
+ if (int.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int result))
+ return result;
+
+ return 0; // 或 return DependencyProperty.UnsetValue;
+ }
+ }
+}
diff --git a/ATS/Converters/HexToDecimalConverter.cs b/ATS/Converters/HexToDecimalConverter.cs
new file mode 100644
index 0000000..17bcd14
--- /dev/null
+++ b/ATS/Converters/HexToDecimalConverter.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class HexToDecimalConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+
+ // 将模型中的十进制值转换为十六进制字符串显示
+ if (value != null)
+ {
+ if (value.GetType() == typeof(int) && value is int intValue)
+ {
+ return $"0x{intValue:X}";
+ }
+ }
+ return value!;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ // 将用户输入的十六进制字符串(如 "0x13A")转换回十进制整数
+ if (value is string stringValue && !string.IsNullOrEmpty(stringValue))
+ {
+ // 移除可能存在的空格
+ stringValue = stringValue.Trim();
+
+ // 检查是否以 "0x" 或 "0X" 开头
+ if (stringValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase)&& stringValue.Length>2)
+ {
+ try
+ {
+ // 移除 "0x" 前缀,然后解析为整数
+ var hexString = stringValue.Substring(2);
+ return System.Convert.ToInt32(hexString, 16);
+ }
+ catch (FormatException)
+ {
+ // 如果格式错误,返回 null 或者抛出异常,取决于您的需求
+ // 这里我们返回 null,让绑定系统保持原值或触发验证
+ return Binding.DoNothing;
+ }
+ catch (OverflowException)
+ {
+ return Binding.DoNothing;
+ }
+ }
+ else
+ {
+ // 如果没有 "0x" 前缀,则尝试按十进制解析
+ try
+ {
+ return System.Convert.ToInt32(stringValue);
+ }
+ catch (FormatException)
+ {
+ return Binding.DoNothing;
+ }
+ catch (OverflowException)
+ {
+ return Binding.DoNothing;
+ }
+ }
+ }
+ return Binding.DoNothing;
+ }
+ }
+}
diff --git a/ATS/Converters/IsEnumTypeConverter .cs b/ATS/Converters/IsEnumTypeConverter .cs
new file mode 100644
index 0000000..00eedb1
--- /dev/null
+++ b/ATS/Converters/IsEnumTypeConverter .cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class IsEnumTypeConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Type type)
+ {
+ // 检查是否为枚举类型
+ bool isEnum = type.IsEnum;
+
+ // 根据参数决定返回值类型
+ if (parameter is string strParam && strParam == "Collapse")
+ {
+ return isEnum ? Visibility.Collapsed : Visibility.Visible;
+ }
+ return isEnum ? Visibility.Visible : Visibility.Collapsed;
+ }
+ return Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/ParameterCategoryToStringConverter.cs b/ATS/Converters/ParameterCategoryToStringConverter.cs
new file mode 100644
index 0000000..d1d4c76
--- /dev/null
+++ b/ATS/Converters/ParameterCategoryToStringConverter.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using static ATS.Models.ParameterModel;
+
+namespace ATS.Converters
+{
+ public class ParameterCategoryToStringConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+
+ if (value is ParameterCategory category)
+ {
+ switch (category)
+ {
+ case ParameterCategory.Input:
+ return "输入";
+ case ParameterCategory.Output:
+ return "输出";
+ case ParameterCategory.Temp:
+ return "缓存";
+ default:
+ return "未知";
+ }
+ }
+ return "未知";
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/ParameterCategoryToVisibilityConverter.cs b/ATS/Converters/ParameterCategoryToVisibilityConverter.cs
new file mode 100644
index 0000000..6ed94fc
--- /dev/null
+++ b/ATS/Converters/ParameterCategoryToVisibilityConverter.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using static ATS.Models.ParameterModel;
+
+namespace ATS.Converters
+{
+ public class ParameterCategoryToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is ParameterCategory category)
+ {
+ if (parameter?.ToString() == "Item")
+ {
+ if(category == ParameterCategory.Temp) { return Visibility.Collapsed; }
+ else { return Visibility.Visible; }
+ }
+ bool boolValue = category == ParameterCategory.Input;
+ if (parameter?.ToString() == "Inverse")
+ {
+ boolValue = !boolValue;
+ }
+ return boolValue ? Visibility.Visible : Visibility.Collapsed;
+ }
+ return Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/ParameterToGotoSettingStringConverter.cs b/ATS/Converters/ParameterToGotoSettingStringConverter.cs
new file mode 100644
index 0000000..58e903a
--- /dev/null
+++ b/ATS/Converters/ParameterToGotoSettingStringConverter.cs
@@ -0,0 +1,119 @@
+using ATS.Windows;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ internal class ParameterToGotoSettingStringConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Guid stepID && stepID == MainWindow.Instance.SelectedStep!.ID)
+ {
+ if (MainWindow.Instance.SelectedStep == null)
+ {
+ return "";
+ }
+ if (MainWindow.Instance.SelectedStep!.OKGotoStepID == null && MainWindow.Instance.SelectedStep!.NGGotoStepID == null)
+ {
+ return "0/0";
+ }
+ else
+ {
+ string gotoString = "";
+ if (MainWindow.Instance.SelectedStep!.OKGotoStepID != null)
+ {
+ var OKGotoStep = MainWindow.Instance.Program.StepCollection.FirstOrDefault(x => x.ID == MainWindow.Instance.SelectedStep!.OKGotoStepID);
+ if (OKGotoStep != null)
+ {
+ gotoString = OKGotoStep.Index.ToString() + "/";
+ }
+ else
+ {
+ gotoString = "0/";
+ }
+ }
+ else
+ {
+ gotoString = "0/";
+ }
+ if (MainWindow.Instance.SelectedStep!.NGGotoStepID != null)
+ {
+ var NGGotoStep = MainWindow.Instance.Program.StepCollection.FirstOrDefault(x => x.ID == MainWindow.Instance.SelectedStep!.NGGotoStepID);
+ if (NGGotoStep != null)
+ {
+ gotoString += NGGotoStep.Index.ToString();
+ }
+ else
+ {
+ gotoString += "0";
+ }
+ }
+ else
+ {
+ gotoString += "0";
+ }
+ return gotoString;
+ }
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is string gotoSettingstring)
+ {
+ gotoSettingstring = gotoSettingstring.Replace(" ", "").Replace("/n", "").Replace("/r", "");
+ if (gotoSettingstring == "0/0")
+ {
+ MainWindow.Instance.SelectedStep!.OKGotoStepID = null;
+ MainWindow.Instance.SelectedStep!.NGGotoStepID = null;
+ }
+ else
+ {
+ try
+ {
+ var list = gotoSettingstring.Split("/");
+ var okindex = System.Convert.ToInt32(list[0]);
+ var ngindex = System.Convert.ToInt32(list[1]);
+ if (okindex == 0)
+ {
+ MainWindow.Instance.SelectedStep!.OKGotoStepID = null;
+ }
+ else
+ {
+ if (okindex > MainWindow.Instance.Program.StepCollection.Count)
+ {
+ throw new Exception("步骤序号超出最大值");
+ }
+ MainWindow.Instance.SelectedStep!.OKGotoStepID = MainWindow.Instance.Program.StepCollection.FirstOrDefault(x => x.Index == okindex)?.ID;
+ }
+ if (ngindex == 0)
+ {
+ MainWindow.Instance.SelectedStep!.NGGotoStepID = null;
+ }
+ else
+ {
+ if (ngindex > MainWindow.Instance.Program.StepCollection.Count)
+ {
+ throw new Exception("步骤序号超出最大值");
+ }
+ MainWindow.Instance.SelectedStep!.NGGotoStepID = MainWindow.Instance.Program.StepCollection.FirstOrDefault(x => x.Index == ngindex)?.ID;
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"跳转表达式错误:{ex.Message}");
+ }
+ }
+ }
+ return MainWindow.Instance.SelectedStep!.ID;
+ }
+ }
+}
diff --git a/ATS/Converters/ParameterTypeToBoolConverter.cs b/ATS/Converters/ParameterTypeToBoolConverter.cs
new file mode 100644
index 0000000..f00819c
--- /dev/null
+++ b/ATS/Converters/ParameterTypeToBoolConverter.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class ParameterTypeToBoolConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if(value is Type type)
+ {
+ if(type == typeof(CancellationToken))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ATS/Converters/ParameterValueToStringConverter.cs b/ATS/Converters/ParameterValueToStringConverter.cs
new file mode 100644
index 0000000..20b393a
--- /dev/null
+++ b/ATS/Converters/ParameterValueToStringConverter.cs
@@ -0,0 +1,38 @@
+using ControlzEx.Standard;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace ATS.Converters
+{
+ public class ParameterValueToStringConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is IEnumerable enumerable && !(value is string))
+ {
+ var elements = enumerable.Cast