diff --git a/DMS.WPF/DMS.WPF.csproj b/DMS.WPF/DMS.WPF.csproj index fe6ba64..70d999b 100644 --- a/DMS.WPF/DMS.WPF.csproj +++ b/DMS.WPF/DMS.WPF.csproj @@ -79,7 +79,7 @@ Wpf Designer - + MSBuild:Compile Wpf Designer @@ -139,6 +139,11 @@ Wpf Designer + + MSBuild:Compile + Wpf + Designer + diff --git a/DMS.WPF/Services/DialogService.cs b/DMS.WPF/Services/DialogService.cs index 1bd8a68..47f2668 100644 --- a/DMS.WPF/Services/DialogService.cs +++ b/DMS.WPF/Services/DialogService.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Windows; +using DMS.WPF.Views; +using DMS.WPF.Views.HandyDialogs; using iNKORE.UI.WPF.Modern.Controls; namespace DMS.WPF.Services @@ -17,6 +19,7 @@ namespace DMS.WPF.Services { typeof(ConfrimDialogViewModel), typeof(ConfirmDialog) }, { typeof(VariableTableDialogViewModel), typeof(VariableTableDialog) }, { typeof(ImportExcelDialogViewModel), typeof(ImportExcelDialog) }, + { typeof(VariableDialogViewModel), typeof(VariableEditorDialog) }, // { typeof(MqttDialogViewModel), typeof(MqttDialog) }, // Add other mappings here // ... other dialogs }; diff --git a/DMS.WPF/ViewModels/DeviceDetailViewModel.cs b/DMS.WPF/ViewModels/DeviceDetailViewModel.cs index 8943730..ba9db76 100644 --- a/DMS.WPF/ViewModels/DeviceDetailViewModel.cs +++ b/DMS.WPF/ViewModels/DeviceDetailViewModel.cs @@ -44,7 +44,7 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable { VariableTableDialogViewModel variableTableDialogViewModel = new VariableTableDialogViewModel() { - PrimaryButContent = "添加变量表" + PrimaryButText = "添加变量表" }; // 1. 显示添加设备对话框 var variableTableItemViewModel = await _dialogService.ShowDialogAsync(variableTableDialogViewModel); @@ -86,7 +86,7 @@ public partial class DeviceDetailViewModel : ViewModelBase, INavigatable VariableTableDialogViewModel variableTableDialogViewModel = new VariableTableDialogViewModel(SelectedVariableTable) { - PrimaryButContent = "编辑变量表" + PrimaryButText = "编辑变量表" }; // 1. 显示变量表对话框 VariableTableItemViewModel variableTable = await _dialogService.ShowDialogAsync(variableTableDialogViewModel); diff --git a/DMS.WPF/ViewModels/DevicesViewModel.cs b/DMS.WPF/ViewModels/DevicesViewModel.cs index 82078e8..44cfe14 100644 --- a/DMS.WPF/ViewModels/DevicesViewModel.cs +++ b/DMS.WPF/ViewModels/DevicesViewModel.cs @@ -87,7 +87,7 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable { DeviceDialogViewModel deviceDialogViewModel = new DeviceDialogViewModel() { - PrimaryButContent = "添加设备" + PrimaryButText = "添加设备" }; // 1. 显示添加设备对话框 DeviceItemViewModel device = await _dialogService.ShowDialogAsync(deviceDialogViewModel); @@ -190,7 +190,7 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable DeviceDialogViewModel deviceDialogViewModel = new DeviceDialogViewModel(SelectedDevice) { - PrimaryButContent = "编辑设备" + PrimaryButText = "编辑设备" }; // 1. 显示设备对话框 DeviceItemViewModel device = await _dialogService.ShowDialogAsync(deviceDialogViewModel); diff --git a/DMS.WPF/ViewModels/Dialogs/ConfrimDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/ConfrimDialogViewModel.cs index 5dcc63b..ef74686 100644 --- a/DMS.WPF/ViewModels/Dialogs/ConfrimDialogViewModel.cs +++ b/DMS.WPF/ViewModels/Dialogs/ConfrimDialogViewModel.cs @@ -13,7 +13,7 @@ public partial class ConfrimDialogViewModel : DialogViewModelBase { Message = message; Title = title; - PrimaryButContent = primaryButText; + PrimaryButText = primaryButText; } diff --git a/DMS.WPF/ViewModels/Dialogs/DialogViewModelBase.cs b/DMS.WPF/ViewModels/Dialogs/DialogViewModelBase.cs index 1eadab3..0abad5d 100644 --- a/DMS.WPF/ViewModels/Dialogs/DialogViewModelBase.cs +++ b/DMS.WPF/ViewModels/Dialogs/DialogViewModelBase.cs @@ -11,7 +11,7 @@ namespace DMS.WPF.ViewModels.Dialogs private string _title; [ObservableProperty] - private string _primaryButContent; + private string _primaryButText; public event Func CloseRequested; diff --git a/DMS.WPF/ViewModels/Dialogs/VarDataDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/VarDataDialogViewModel.cs deleted file mode 100644 index fa0dcf3..0000000 --- a/DMS.WPF/ViewModels/Dialogs/VarDataDialogViewModel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using DMS.WPF.ViewModels.Items; - -namespace DMS.WPF.ViewModels.Dialogs; - -public partial class VarDataDialogViewModel : ObservableObject -{ - [ObservableProperty] - private VariableItemViewModel _variable; - [ObservableProperty] - private string title; - [ObservableProperty] - private string primaryButtonText; -} \ No newline at end of file diff --git a/DMS.WPF/ViewModels/Dialogs/VariableDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/VariableDialogViewModel.cs new file mode 100644 index 0000000..c2a22dc --- /dev/null +++ b/DMS.WPF/ViewModels/Dialogs/VariableDialogViewModel.cs @@ -0,0 +1,37 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using DMS.WPF.ViewModels.Items; + +namespace DMS.WPF.ViewModels.Dialogs; + +public partial class VariableDialogViewModel : DialogViewModelBase +{ + [ObservableProperty] + private VariableItemViewModel _variable; + + public VariableDialogViewModel(string title,string primaryButText,VariableItemViewModel variable=null) + { + if (variable==null) + { + Variable=new VariableItemViewModel(); + } + else + { + Variable=variable; + } + + Title=title; + PrimaryButText=primaryButText; + } + + [RelayCommand] + private void PrimaryButton() + { + Close(Variable); + } + [RelayCommand] + private void CancleButton() + { + Close(null); + } +} \ No newline at end of file diff --git a/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs b/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs index 55a5bc0..e356a17 100644 --- a/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs +++ b/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs @@ -6,88 +6,190 @@ using System.Collections.Generic; namespace DMS.WPF.ViewModels.Items; +/// +/// 表示单个变量项的视图模型。 +/// 此类用于UI层的数据绑定,封装了变量数据以及与UI相关的状态和逻辑。 +/// 它继承自 ObservableObject,以便于实现 INotifyPropertyChanged 接口,从而支持WPF的双向绑定。 +/// public partial class VariableItemViewModel : ObservableObject { + /// + /// 获取或设置变量的唯一标识符 (ID)。 + /// 通常对应数据库中的主键。 + /// public int Id { get; set; } + /// + /// 获取或设置变量的名称。 + /// 这个名称会显示在UI界面上,例如在列表或标签中。 + /// [ObservableProperty] 特性会自动生成支持变更通知的属性。 + /// [ObservableProperty] private string _name; + /// + /// 获取或设置变量的S7通信地址。 + /// 例如:"DB1.DBD0"。仅在协议为S7时有效。 + /// [ObservableProperty] private string? _s7Address; + /// + /// 获取或设置从设备读取到的原始数据值。 + /// 这通常是未经转换的字符串形式的值。 + /// [ObservableProperty] private string? _dataValue; + /// + /// 获取或设置用于在界面上显示的值。 + /// 这可能是经过公式转换、格式化或添加了单位后的值。 + /// [ObservableProperty] private string? _displayValue; + /// + /// 获取或设置此变量所属的变量表 (VariableTable) 的数据传输对象 (DTO)。 + /// 用于在界面上显示变量表的关联信息。 + /// [ObservableProperty] private VariableTableDto? _variableTable; + /// + /// 获取或设置与此变量关联的MQTT别名列表。 + /// 一个变量可以有多个MQTT别名。 + /// [ObservableProperty] private List? _mqttAliases; + /// + /// 获取或设置变量的信号类型 (如:AI, DI, AO, DO)。 + /// [ObservableProperty] private SignalType _signalType ; + /// + /// 获取或设置变量的轮询等级。 + /// 用于决定数据采集的频率(如:高、中、低)。 + /// [ObservableProperty] private PollLevelType _pollLevel; + /// + /// 获取或设置一个值,该值指示此变量是否被激活。 + /// 未激活的变量将不会被后台服务轮询。 + /// [ObservableProperty] private bool _isActive; + /// + /// 获取或设置变量所属的变量表的ID。 + /// [ObservableProperty] private int _variableTableId; + /// + /// 获取或设置变量的OPC UA节点ID。 + /// 例如:"ns=2;s=MyDevice.MyVariable"。仅在协议为OpcUa时有效。 + /// [ObservableProperty] private string _opcUaNodeId; + /// + /// 获取或设置是否为此变量启用历史记录。 + /// [ObservableProperty] private bool _isHistoryEnabled; + /// + /// 获取或设置历史记录的死区值。 + /// 当值的变化超过此死区值时,才会记录历史数据,用于减少不必要的数据存储。 + /// [ObservableProperty] private double _historyDeadband; + /// + /// 获取或设置是否为此变量启用报警功能。 + /// [ObservableProperty] private bool _isAlarmEnabled; + /// + /// 获取或设置报警的下限值。 + /// [ObservableProperty] private double _alarmMinValue; + /// + /// 获取或设置报警的上限值。 + /// [ObservableProperty] private double _alarmMaxValue; + /// + /// 获取或设置报警的死区值。 + /// 用于防止在临界点附近频繁触发或解除报警。 + /// [ObservableProperty] private double _alarmDeadband; + /// + /// 获取或设置变量使用的通信协议(如:S7, OpcUa, Modbus)。 + /// [ObservableProperty] private ProtocolType _protocol; + /// + /// 获取或设置变量在C#中对应的数据类型。 + /// [ObservableProperty] private CSharpDataType _cSharpDataType; + /// + /// 获取或设置值的转换公式。 + /// 例如:"x * 10" 或 "(x / 100) + 5"。'x' 代表原始值。 + /// [ObservableProperty] private string _conversionFormula; + /// + /// 获取或设置记录的创建时间。 + /// [ObservableProperty] private DateTime _createdAt; + /// + /// 获取或设置记录的最后更新时间。 + /// [ObservableProperty] private DateTime _updatedAt; + /// + /// 获取或设置最后更新此记录的用户或进程。 + /// [ObservableProperty] private string _updatedBy; + /// + /// 获取或设置一个值,该值指示此视图模型中的数据是否已被修改。 + /// 用于跟踪UI上的更改,以便提示用户保存。 + /// [ObservableProperty] private bool _isModified; + /// + /// 获取或设置变量的描述信息。 + /// 提供关于该变量的更多上下文或备注。 + /// [ObservableProperty] private string _description; + /// + /// 获取或设置OPC UA值的更新方式(轮询或订阅)。 + /// [ObservableProperty] private OpcUaUpdateType _opcUaUpdateType; -} +} \ No newline at end of file diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index 0af05b0..e860d74 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -9,11 +9,17 @@ using DMS.WPF.ViewModels.Dialogs; using DMS.WPF.ViewModels.Items; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Windows; using System.Windows.Data; using DMS.Application.DTOs; using DMS.Application.Interfaces; using DMS.Application.Services; using DMS.Helper; +using DMS.WPF.Views; +using DMS.WPF.Views.HandyDialogs; +using HandyControl.Controls; +using HandyControl.Data; +using HandyControl.Tools.Extension; using Microsoft.Extensions.DependencyInjection; using ObservableCollections; @@ -482,78 +488,88 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 当前操作的变量表,用于设置新变量的所属ID。 [RelayCommand] - private async void AddVarData(VariableTable variableTable) + private async void AddVariable(VariableTable variableTable) { - // try - // { - // // 显示添加变量数据的对话框 - // var varData = await _dialogService.ShowAddVarDataDialog(); - // - // // 如果用户取消或对话框未返回数据,则直接返回 - // if (varData == null) - // return; - // - // // 设置新变量的所属变量表ID - // varData.VariableTableId = variableTable.Id; - // - // // --- 重复性检查逻辑开始 --- - // bool isDuplicate = false; - // string duplicateReason = string.Empty; - // - // // 检查名称是否重复 - // if (Variables.Any(v => v.Name == varData.Name)) - // { - // isDuplicate = true; - // duplicateReason = $"名称 '{varData.Name}' 已存在。"; - // } - // else - // { - // // 根据协议类型检查S7地址或NodeId是否重复 - // if (variableTable.ProtocolType == ProtocolType.S7) - // { - // if (!string.IsNullOrEmpty(varData.S7Address) && - // Variables.Any(v => v.S7Address == varData.S7Address)) - // { - // isDuplicate = true; - // duplicateReason = $"S7地址 '{varData.S7Address}' 已存在。"; - // } - // } - // else if (variableTable.ProtocolType == ProtocolType.OpcUA) - // { - // if (!string.IsNullOrEmpty(varData.NodeId) && Variables.Any(v => v.NodeId == varData.NodeId)) - // { - // isDuplicate = true; - // duplicateReason = $"OPC UA NodeId '{varData.NodeId}' 已存在。"; - // } - // } - // } - // - // if (isDuplicate) - // { - // NotificationHelper.ShowError($"添加变量失败:{duplicateReason}"); - // return; - // } - // // --- 重复性检查逻辑结束 --- - // - // // 添加变量数据到数据库 - // var resVarData = await _varDataRepository.AddAsync(varData); - // if (resVarData == null) - // { - // NotificationHelper.ShowError($"添加变量失败了:{varData?.Name}"); - // return; - // } - // - // // 更新当前页面显示的数据:将新变量添加到集合中 - // Variables.Add(resVarData); - // - // // 显示成功通知 - // NotificationHelper.ShowSuccess($"添加变量成功:{varData?.Name}"); - // } - // catch (Exception e) - // { - // // 捕获并显示错误通知 - // NotificationHelper.ShowError($"添加变量的过程中发生了不可预期的错误:{e.Message}", e); - // } + try + { + // 显示添加变量数据的对话框 + VariableDialogViewModel variableDialogViewModel=new VariableDialogViewModel("添加变量","添加变量"); + + VariableEditorDialog editorDialog = new VariableEditorDialog() { DataContext = variableDialogViewModel }; + + Dialog.Show(new MessageBoxInfo() + { + Message = "操作成功", + Caption = "提示", + Button = MessageBoxButton.OKCancel, + }); + // var variableItemViewModel = await _dialogService.ShowDialogAsync(variableDialogViewModel); + + // 如果用户取消或对话框未返回数据,则直接返回 + // if (res == null) + // return; + + // // 设置新变量的所属变量表ID + // varData.VariableTableId = variableTable.Id; + // + // // --- 重复性检查逻辑开始 --- + // bool isDuplicate = false; + // string duplicateReason = string.Empty; + // + // // 检查名称是否重复 + // if (Variables.Any(v => v.Name == varData.Name)) + // { + // isDuplicate = true; + // duplicateReason = $"名称 '{varData.Name}' 已存在。"; + // } + // else + // { + // // 根据协议类型检查S7地址或NodeId是否重复 + // if (variableTable.ProtocolType == ProtocolType.S7) + // { + // if (!string.IsNullOrEmpty(varData.S7Address) && + // Variables.Any(v => v.S7Address == varData.S7Address)) + // { + // isDuplicate = true; + // duplicateReason = $"S7地址 '{varData.S7Address}' 已存在。"; + // } + // } + // else if (variableTable.ProtocolType == ProtocolType.OpcUA) + // { + // if (!string.IsNullOrEmpty(varData.NodeId) && Variables.Any(v => v.NodeId == varData.NodeId)) + // { + // isDuplicate = true; + // duplicateReason = $"OPC UA NodeId '{varData.NodeId}' 已存在。"; + // } + // } + // } + // + // if (isDuplicate) + // { + // NotificationHelper.ShowError($"添加变量失败:{duplicateReason}"); + // return; + // } + // // --- 重复性检查逻辑结束 --- + // + // // 添加变量数据到数据库 + // var resVarData = await _varDataRepository.AddAsync(varData); + // if (resVarData == null) + // { + // NotificationHelper.ShowError($"添加变量失败了:{varData?.Name}"); + // return; + // } + // + // // 更新当前页面显示的数据:将新变量添加到集合中 + // Variables.Add(resVarData); + // + // // 显示成功通知 + // NotificationHelper.ShowSuccess($"添加变量成功:{varData?.Name}"); + } + catch (Exception e) + { + // 捕获并显示错误通知 + NotificationHelper.ShowError($"添加变量的过程中发生了不可预期的错误:{e.Message}", e); + } } /// diff --git a/DMS.WPF/Views/Dialogs/ConfirmDialog.xaml b/DMS.WPF/Views/Dialogs/ConfirmDialog.xaml index d8e064d..e0adb70 100644 --- a/DMS.WPF/Views/Dialogs/ConfirmDialog.xaml +++ b/DMS.WPF/Views/Dialogs/ConfirmDialog.xaml @@ -12,7 +12,7 @@ Title="{Binding Title}" CloseButtonText="取消" DefaultButton="Primary" - PrimaryButtonText="{Binding PrimaryButContent}" + PrimaryButtonText="{Binding PrimaryButText}" Background="#fff" d:DataContext="{d:DesignInstance vmd:ConfrimDialogViewModel}" mc:Ignorable="d"> diff --git a/DMS.WPF/Views/Dialogs/DeviceDialog.xaml b/DMS.WPF/Views/Dialogs/DeviceDialog.xaml index 8c71897..e33dc8d 100644 --- a/DMS.WPF/Views/Dialogs/DeviceDialog.xaml +++ b/DMS.WPF/Views/Dialogs/DeviceDialog.xaml @@ -13,7 +13,7 @@ Title="{Binding Title}" CloseButtonText="取消" DefaultButton="Primary" - PrimaryButtonText="{Binding PrimaryButContent}" + PrimaryButtonText="{Binding PrimaryButText}" d:DataContext="{d:DesignInstance vmd:DeviceDialogViewModel}" mc:Ignorable="d"> diff --git a/DMS.WPF/Views/Dialogs/MqttDialog.xaml b/DMS.WPF/Views/Dialogs/MqttDialog.xaml index 7030ad1..d3e4110 100644 --- a/DMS.WPF/Views/Dialogs/MqttDialog.xaml +++ b/DMS.WPF/Views/Dialogs/MqttDialog.xaml @@ -13,7 +13,7 @@ Title="{Binding Title}" CloseButtonText="取消" DefaultButton="Primary" - PrimaryButtonText="{Binding PrimaryButContent}" + PrimaryButtonText="{Binding PrimaryButText}" Background="#fff" d:DataContext="{d:DesignInstance vmd:MqttDialogViewModel}" mc:Ignorable="d"> diff --git a/DMS.WPF/Views/Dialogs/VarDataDialog.xaml.cs b/DMS.WPF/Views/Dialogs/VarDataDialog.xaml.cs deleted file mode 100644 index 15eebf1..0000000 --- a/DMS.WPF/Views/Dialogs/VarDataDialog.xaml.cs +++ /dev/null @@ -1,16 +0,0 @@ -using DMS.WPF.ViewModels.Dialogs; - -namespace DMS.WPF.Views.Dialogs; - -public partial class VarDataDialog -{ - public VarDataDialog() - { - InitializeComponent(); - } - - public VarDataDialog(VarDataDialogViewModel viewModel) : this() - { - DataContext = viewModel; - } -} \ No newline at end of file diff --git a/DMS.WPF/Views/Dialogs/VarDataDialog.xaml b/DMS.WPF/Views/Dialogs/VariableDialog.xaml similarity index 76% rename from DMS.WPF/Views/Dialogs/VarDataDialog.xaml rename to DMS.WPF/Views/Dialogs/VariableDialog.xaml index 996d85a..adb11ee 100644 --- a/DMS.WPF/Views/Dialogs/VarDataDialog.xaml +++ b/DMS.WPF/Views/Dialogs/VariableDialog.xaml @@ -1,4 +1,4 @@ - + + + + + + + + + - + + - - - - - + @@ -47,11 +55,11 @@ - + - @@ -63,7 +71,7 @@ - + @@ -79,7 +87,7 @@ - @@ -91,13 +99,13 @@ - + - + + IsChecked="{Binding Variable.IsHistoryEnabled, UpdateSourceTrigger=PropertyChanged}" /> @@ -116,18 +124,22 @@ - + - + + IsChecked="{Binding Variable.IsAlarmEnabled, UpdateSourceTrigger=PropertyChanged}" /> - + + + + + \ No newline at end of file diff --git a/DMS.WPF/Views/Dialogs/VariableDialog.xaml.cs b/DMS.WPF/Views/Dialogs/VariableDialog.xaml.cs new file mode 100644 index 0000000..081ac89 --- /dev/null +++ b/DMS.WPF/Views/Dialogs/VariableDialog.xaml.cs @@ -0,0 +1,14 @@ +using DMS.WPF.ViewModels.Dialogs; + +namespace DMS.WPF.Views.Dialogs; + +public partial class VariableDialog +{ + public VariableDialog() + { + InitializeComponent(); + + + } + +} \ No newline at end of file diff --git a/DMS.WPF/Views/Dialogs/VariableTableDialog.xaml b/DMS.WPF/Views/Dialogs/VariableTableDialog.xaml index 95ced43..49cd45f 100644 --- a/DMS.WPF/Views/Dialogs/VariableTableDialog.xaml +++ b/DMS.WPF/Views/Dialogs/VariableTableDialog.xaml @@ -10,7 +10,7 @@ Title="{Binding Title}" CloseButtonText="取消" DefaultButton="Primary" - PrimaryButtonText="{Binding PrimaryButContent}" + PrimaryButtonText="{Binding PrimaryButText}" Background="#fff" d:DataContext="{d:DesignInstance vmd:VariableTableDialogViewModel}" mc:Ignorable="d"> diff --git a/DMS.WPF/Views/HandyDialogs/VariableEditorDialog.xaml b/DMS.WPF/Views/HandyDialogs/VariableEditorDialog.xaml new file mode 100644 index 0000000..0766361 --- /dev/null +++ b/DMS.WPF/Views/HandyDialogs/VariableEditorDialog.xaml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +