添加注释,修复一些BUG
This commit is contained in:
@@ -68,11 +68,10 @@ public class VarDataRepository
|
|||||||
{
|
{
|
||||||
var result = await _db.Queryable<DbVariableData>()
|
var result = await _db.Queryable<DbVariableData>()
|
||||||
.Where(d => d.VariableTableId == varTableId)
|
.Where(d => d.VariableTableId == varTableId)
|
||||||
.Select(dbVarData => dbVarData.CopyTo<VariableData>())
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
NlogHelper.Info($"获取变量表的所有变量{result.Count()}个耗时:{stopwatch.ElapsedMilliseconds}ms");
|
NlogHelper.Info($"获取变量表的所有变量{result.Count()}个耗时:{stopwatch.ElapsedMilliseconds}ms");
|
||||||
return result;
|
return result.Select(d=>d.CopyTo<VariableData>()).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,353 +15,566 @@ using PMSWPF.Services;
|
|||||||
|
|
||||||
namespace PMSWPF.ViewModels;
|
namespace PMSWPF.ViewModels;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// VariableTableViewModel 是用于管理和显示变量表数据的视图模型。
|
||||||
|
/// 它与 VariableTableView 视图进行数据绑定,并处理用户交互逻辑。
|
||||||
|
///
|
||||||
|
/// 调用逻辑概述:
|
||||||
|
/// 1. **实例化**: 当导航到 VariableTableView 时,通常会通过依赖注入框架(如 CommunityToolkit.Mvvm 的服务定位器或自定义工厂)实例化 VariableTableViewModel。
|
||||||
|
/// 构造函数 <see cref="VariableTableViewModel(IDialogService)"/> 负责初始化必要的服务和数据仓库。
|
||||||
|
/// 2. **数据加载**:
|
||||||
|
/// - 当视图加载完成时,框架会自动调用 <see cref="OnLoaded"/> 方法。
|
||||||
|
/// - 此方法会根据传入的 <see cref="VariableTable"/> 对象初始化 <see cref="DataVariables"/> 集合,并设置协议类型相关的布尔属性。
|
||||||
|
/// - 它还会创建 <see cref="_originalDataVariables"/> 的深拷贝,用于在用户取消保存时还原数据。
|
||||||
|
/// 3. **数据绑定与显示**:
|
||||||
|
/// - <see cref="VariableTable"/> 属性绑定到视图中显示的当前变量表信息。
|
||||||
|
/// - <see cref="DataVariables"/> 属性(ObservableCollection)绑定到视图中的数据网格或列表,用于显示变量数据。
|
||||||
|
/// - <see cref="VariableDataView"/> 是一个 ICollectionView,用于支持数据过滤(通过 <see cref="FilterVariables"/> 方法)和排序。
|
||||||
|
/// - <see cref="SearchText"/> 属性绑定到搜索框,当其值改变时,会自动触发 <see cref="OnSearchTextChanged(string)"/> 方法刷新视图。
|
||||||
|
/// 4. **用户交互与命令**:
|
||||||
|
/// - 视图中的按钮和其他交互元素通过 `RelayCommand` 绑定到 ViewModel 中的命令方法。
|
||||||
|
/// - 例如,"保存"按钮可能绑定到 <see cref="SaveModifiedVarDataCommand"/>,"编辑"按钮绑定到 <see cref="EditVarDataCommand"/> 等。
|
||||||
|
/// - 这些命令方法负责执行业务逻辑,如更新数据库、显示对话框、导入数据等。
|
||||||
|
/// 5. **对话框交互**:
|
||||||
|
/// - ViewModel 通过注入的 <see cref="IDialogService"/> 接口与各种对话框进行交互,例如确认对话框、编辑对话框、导入对话框等。
|
||||||
|
/// - 对话框的显示和结果处理都在 ViewModel 中完成。
|
||||||
|
/// 6. **数据保存与退出**:
|
||||||
|
/// - 当用户尝试离开当前视图时,框架会调用 <see cref="OnExitAsync"/> 方法。
|
||||||
|
/// - 此方法会检查是否有未保存的修改,并提示用户是否保存或放弃更改。
|
||||||
|
/// - <see cref="SaveModifiedVarDataCommand"/> 用于显式保存修改。
|
||||||
|
/// 7. **通知**:
|
||||||
|
/// - 通过 <see cref="NotificationHelper"/> 显示成功、错误或信息提示给用户。
|
||||||
|
/// 8. **协议类型切换**:
|
||||||
|
/// - <see cref="IsS7ProtocolSelected"/> 和 <see cref="IsOpcUaProtocolSelected"/> 属性用于控制视图中与协议相关的UI元素的可见性或状态。
|
||||||
|
/// </summary>
|
||||||
partial class VariableTableViewModel : ViewModelBase
|
partial class VariableTableViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 对话服务接口,用于显示各种对话框(如确认、编辑、导入等)。
|
||||||
|
/// </summary>
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前正在操作的变量表实体。
|
||||||
|
/// 通过 ObservableProperty 自动生成 VariableTable 属性和 OnVariableTableChanged 方法。
|
||||||
|
/// </summary>
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private VariableTable variableTable;
|
private VariableTable variableTable;
|
||||||
private ObservableCollection<VariableData> _dataVariables = new ObservableCollection<VariableData>();
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 存储当前变量表中的所有变量数据的集合。
|
||||||
|
/// 通过 ObservableProperty 自动生成 DataVariables 属性和 OnDataVariablesChanged 方法。
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private ObservableCollection<VariableData> _dataVariables;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前选中的变量数据。
|
||||||
|
/// 通过 ObservableProperty 自动生成 SelectedVariableData 属性和 OnSelectedVariableDataChanged 方法。
|
||||||
|
/// </summary>
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private VariableData _selectedVariableData;
|
private VariableData _selectedVariableData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于过滤变量数据的搜索文本。
|
||||||
|
/// 通过 ObservableProperty 自动生成 SearchText 属性和 OnSearchTextChanged 方法。
|
||||||
|
/// </summary>
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _searchText;
|
private string _searchText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于在UI中显示和过滤变量数据的视图集合。
|
||||||
|
/// </summary>
|
||||||
public ICollectionView VariableDataView { get; private set; }
|
public ICollectionView VariableDataView { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否是第一次加载,防止ToggleSwitch第一次加载触发改变事件
|
/// 指示视图是否已完成首次加载。
|
||||||
|
/// 用于防止某些UI控件(如ToggleSwitch)在初始化时触发不必要的事件。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsLoadCompletion { get; set; } = false;
|
public bool IsLoadCompletion { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 变量表数据仓库,用于与变量表相关的数据库操作。
|
||||||
|
/// </summary>
|
||||||
private readonly VarTableRepository _varTableRepository;
|
private readonly VarTableRepository _varTableRepository;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 变量数据仓库,用于与变量数据相关的数据库操作。
|
||||||
|
/// </summary>
|
||||||
private readonly VarDataRepository _varDataRepository;
|
private readonly VarDataRepository _varDataRepository;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原始变量数据的深拷贝备份,用于在用户取消保存时还原数据。
|
||||||
|
/// </summary>
|
||||||
private ObservableCollection<VariableData>? _originalDataVariables;
|
private ObservableCollection<VariableData>? _originalDataVariables;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示当前变量表是否使用S7协议。
|
||||||
|
/// 通过 ObservableProperty 自动生成 IsS7ProtocolSelected 属性。
|
||||||
|
/// </summary>
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isS7ProtocolSelected;
|
private bool _isS7ProtocolSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示当前变量表是否使用OpcUA协议。
|
||||||
|
/// 通过 ObservableProperty 自动生成 IsOpcUaProtocolSelected 属性。
|
||||||
|
/// </summary>
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isOpcUaProtocolSelected;
|
private bool _isOpcUaProtocolSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// VariableTableViewModel 的构造函数。
|
||||||
|
/// 初始化服务、数据仓库和变量数据集合视图。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dialogService">对话服务接口的实例。</param>
|
||||||
public VariableTableViewModel(IDialogService dialogService)
|
public VariableTableViewModel(IDialogService dialogService)
|
||||||
{
|
{
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
IsLoadCompletion = false;
|
IsLoadCompletion = false; // 初始设置为 false,表示未完成加载
|
||||||
_varTableRepository = new VarTableRepository();
|
_varTableRepository = new VarTableRepository();
|
||||||
_varDataRepository = new VarDataRepository();
|
_varDataRepository = new VarDataRepository();
|
||||||
_dataVariables = new ObservableCollection<VariableData>(); // Initialize here
|
_dataVariables = new ObservableCollection<VariableData>(); // 初始化集合
|
||||||
VariableDataView = CollectionViewSource.GetDefaultView(_dataVariables);
|
VariableDataView = CollectionViewSource.GetDefaultView(_dataVariables); // 获取集合视图
|
||||||
VariableDataView.Filter = FilterVariables;
|
VariableDataView.Filter = FilterVariables; // 设置过滤方法
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于过滤 <see cref="VariableDataView"/> 中的变量数据。
|
||||||
|
/// 根据 <see cref="SearchText"/> 属性的值进行模糊匹配。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">要过滤的集合中的单个项。</param>
|
||||||
|
/// <returns>如果项匹配搜索条件则为 true,否则为 false。</returns>
|
||||||
private bool FilterVariables(object item)
|
private bool FilterVariables(object item)
|
||||||
{
|
{
|
||||||
|
// 如果搜索文本为空或空白,则显示所有项
|
||||||
if (string.IsNullOrWhiteSpace(SearchText))
|
if (string.IsNullOrWhiteSpace(SearchText))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 尝试将项转换为 VariableData 类型
|
||||||
if (item is VariableData variable)
|
if (item is VariableData variable)
|
||||||
{
|
{
|
||||||
var searchTextLower = SearchText.ToLower();
|
var searchTextLower = SearchText.ToLower();
|
||||||
return variable.Name?.ToLower().Contains(searchTextLower) == true ||
|
// 检查变量的名称、描述、NodeId、S7地址、数据值或显示值是否包含搜索文本
|
||||||
variable.Description?.ToLower().Contains(searchTextLower) == true ||
|
return variable.Name?.ToLower()
|
||||||
variable.NodeId?.ToLower().Contains(searchTextLower) == true ||
|
.Contains(searchTextLower) == true ||
|
||||||
variable.S7Address?.ToLower().Contains(searchTextLower) == true ||
|
variable.Description?.ToLower()
|
||||||
variable.DataValue?.ToLower().Contains(searchTextLower) == true ||
|
.Contains(searchTextLower) == true ||
|
||||||
variable.DisplayValue?.ToLower().Contains(searchTextLower) == true;
|
variable.NodeId?.ToLower()
|
||||||
|
.Contains(searchTextLower) == true ||
|
||||||
|
variable.S7Address?.ToLower()
|
||||||
|
.Contains(searchTextLower) == true ||
|
||||||
|
variable.DataValue?.ToLower()
|
||||||
|
.Contains(searchTextLower) == true ||
|
||||||
|
variable.DisplayValue?.ToLower()
|
||||||
|
.Contains(searchTextLower) == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当 <see cref="SearchText"/> 属性的值发生改变时自动调用。
|
||||||
|
/// 刷新 <see cref="VariableDataView"/> 以应用新的过滤条件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">新的搜索文本值。</param>
|
||||||
partial void OnSearchTextChanged(string value)
|
partial void OnSearchTextChanged(string value)
|
||||||
{
|
{
|
||||||
VariableDataView?.Refresh();
|
VariableDataView?.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当视图加载完成时调用。
|
||||||
|
/// 初始化协议选择状态,加载变量数据,并创建原始数据的深拷贝备份。
|
||||||
|
/// </summary>
|
||||||
public override void OnLoaded()
|
public override void OnLoaded()
|
||||||
{
|
{
|
||||||
|
// 根据变量表的协议类型设置对应的布尔属性
|
||||||
IsS7ProtocolSelected = VariableTable.ProtocolType == ProtocolType.S7;
|
IsS7ProtocolSelected = VariableTable.ProtocolType == ProtocolType.S7;
|
||||||
IsOpcUaProtocolSelected = VariableTable.ProtocolType == ProtocolType.OpcUA;
|
IsOpcUaProtocolSelected = VariableTable.ProtocolType == ProtocolType.OpcUA;
|
||||||
|
|
||||||
|
// 如果变量表包含数据变量,则进行初始化
|
||||||
if (VariableTable.DataVariables != null)
|
if (VariableTable.DataVariables != null)
|
||||||
{
|
{
|
||||||
_dataVariables = new ObservableCollection<VariableData>(VariableTable.DataVariables);
|
// 将变量表中的数据变量复制到可观察集合中
|
||||||
VariableDataView = CollectionViewSource.GetDefaultView(_dataVariables);
|
_dataVariables.Clear(); // 清空现有集合
|
||||||
VariableDataView.Filter = FilterVariables;
|
foreach (var item in VariableTable.DataVariables)
|
||||||
|
{
|
||||||
|
_dataVariables.Add(item); // 添加新项
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 创建原始数据的深拷贝备份
|
VariableDataView.Refresh(); // 刷新视图以应用过滤和排序
|
||||||
// 推荐使用 JSON 序列化/反序列化进行深度拷贝
|
|
||||||
var serialized = JsonConvert.SerializeObject(_dataVariables);
|
// 创建原始数据的深拷贝备份,用于在取消保存时还原
|
||||||
|
var serialized = JsonConvert.SerializeObject(DataVariables);
|
||||||
_originalDataVariables = JsonConvert.DeserializeObject<ObservableCollection<VariableData>>(serialized);
|
_originalDataVariables = JsonConvert.DeserializeObject<ObservableCollection<VariableData>>(serialized);
|
||||||
|
|
||||||
// 在数据加载完成后,将所有变量的 IsModified 状态重置为 false
|
// 在数据加载完成后,将所有变量的 IsModified 状态重置为 false
|
||||||
foreach (var variableData in _dataVariables)
|
foreach (var variableData in DataVariables)
|
||||||
{
|
{
|
||||||
variableData.IsModified = false;
|
variableData.IsModified = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 标记加载完成
|
||||||
IsLoadCompletion = true;
|
IsLoadCompletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 退出当前实体时调用
|
/// 当用户尝试退出当前视图时异步调用。
|
||||||
|
/// 检查是否有未保存的修改,并提示用户是否保存或放弃更改。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>如果可以安全退出则为 true,否则为 false。</returns>
|
||||||
public override async Task<bool> OnExitAsync()
|
public override async Task<bool> OnExitAsync()
|
||||||
{
|
{
|
||||||
var modifiedDatas = _dataVariables.Where(d => d.IsModified == true)
|
// 查找所有已修改的变量数据
|
||||||
|
var modifiedDatas = DataVariables.Where(d => d.IsModified == true)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
// 如果没有修改,则直接允许退出
|
||||||
if (modifiedDatas.Count == 0)
|
if (modifiedDatas.Count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// 提示用户有未保存的数据,询问是否离开
|
||||||
var isExit = await _dialogService.ShowConfrimeDialog(
|
var isExit = await _dialogService.ShowConfrimeDialog(
|
||||||
"数据未保存", $"你有{modifiedDatas.Count}个修改的变量没有保存,离开后这些数据就可能丢失了确认要离开吗?", "离开");
|
"数据未保存", $"你有{modifiedDatas.Count}个修改的变量没有保存,离开后这些数据就可能丢失了确认要离开吗?", "离开");
|
||||||
|
|
||||||
|
// 如果用户选择不离开(即不保存),则还原数据
|
||||||
if (!isExit)
|
if (!isExit)
|
||||||
{
|
{
|
||||||
// 不保存数据,还原原来的数据
|
// 遍历所有已修改的数据,从原始备份中还原
|
||||||
foreach (var modifiedData in modifiedDatas)
|
foreach (var modifiedData in modifiedDatas)
|
||||||
{
|
{
|
||||||
var oldData = _originalDataVariables.First(od => od.Id == modifiedData.Id);
|
var oldData = _originalDataVariables.First(od => od.Id == modifiedData.Id);
|
||||||
oldData.CopyTo(modifiedData);
|
oldData.CopyTo(modifiedData); // 将原始数据复制回当前数据
|
||||||
modifiedData.IsModified = false;
|
modifiedData.IsModified = false; // 重置修改状态
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false; // 不允许退出
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true; // 允许退出
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存修改过的变量数据
|
/// 保存所有已修改的变量数据到数据库。
|
||||||
|
/// 此命令通常绑定到UI中的“保存”按钮。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async void SaveModifiedVarData()
|
private async void SaveModifiedVarData()
|
||||||
{
|
{
|
||||||
var modifiedDatas = _dataVariables.Where(d => d.IsModified == true)
|
// 查找所有已标记为修改的变量数据
|
||||||
|
var modifiedDatas = DataVariables.Where(d => d.IsModified == true)
|
||||||
.ToList();
|
.ToList();
|
||||||
///更新数据库
|
// 更新数据库中的这些数据
|
||||||
await _varDataRepository.UpdateAsync(modifiedDatas);
|
await _varDataRepository.UpdateAsync(modifiedDatas);
|
||||||
// 还原修改状态
|
|
||||||
|
// 还原所有已保存数据的修改状态
|
||||||
foreach (var modifiedData in modifiedDatas)
|
foreach (var modifiedData in modifiedDatas)
|
||||||
{
|
{
|
||||||
modifiedData.IsModified = false;
|
modifiedData.IsModified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示成功通知
|
||||||
NotificationHelper.ShowSuccess($"修改的{modifiedDatas.Count}变量保存成功.");
|
NotificationHelper.ShowSuccess($"修改的{modifiedDatas.Count}变量保存成功.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 编辑选定的变量数据。
|
||||||
|
/// 此命令通常绑定到UI中的“编辑”按钮或双击事件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableTable">当前操作的变量表,用于更新其内部的变量数据。</param>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async void EditVarData(VariableTable variableTable)
|
private async void EditVarData(VariableTable variableTable)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// // 1. 显示添加设备对话框
|
// 显示编辑变量数据的对话框,并传入当前选中的变量数据
|
||||||
var varData = await _dialogService.ShowEditVarDataDialog(SelectedVariableData);
|
var varData = await _dialogService.ShowEditVarDataDialog(SelectedVariableData);
|
||||||
// // 如果用户取消或对话框未返回设备,则直接返回
|
|
||||||
|
// 如果用户取消或对话框未返回数据,则直接返回
|
||||||
if (varData == null)
|
if (varData == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// 设置变量数据的所属变量表ID
|
||||||
varData.VariableTableId = variableTable.Id;
|
varData.VariableTableId = variableTable.Id;
|
||||||
// 更新数据库
|
|
||||||
|
// 更新数据库中的变量数据
|
||||||
await _varDataRepository.UpdateAsync(varData);
|
await _varDataRepository.UpdateAsync(varData);
|
||||||
// 更新当前页面的
|
|
||||||
|
// 更新当前页面显示的数据:找到原数据在集合中的索引并替换
|
||||||
var index = variableTable.DataVariables.IndexOf(SelectedVariableData);
|
var index = variableTable.DataVariables.IndexOf(SelectedVariableData);
|
||||||
// 更新变量表中的
|
|
||||||
if (index >= 0 && index < variableTable.DataVariables.Count)
|
if (index >= 0 && index < variableTable.DataVariables.Count)
|
||||||
variableTable.DataVariables[index] = varData;
|
variableTable.DataVariables[index] = varData; // 替换为编辑后的数据
|
||||||
|
|
||||||
|
// 显示成功通知
|
||||||
NotificationHelper.ShowSuccess($"编辑变量成功:{varData?.Name}");
|
NotificationHelper.ShowSuccess($"编辑变量成功:{varData?.Name}");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
// 捕获并显示错误通知
|
||||||
NotificationHelper.ShowError($"编辑变量的过程中发生了不可预期的错误:{e.Message}", e);
|
NotificationHelper.ShowError($"编辑变量的过程中发生了不可预期的错误:{e.Message}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从TIA Portal导出的变量表Excel文件中导入变量数据。
|
||||||
|
/// 此命令通常绑定到UI中的“从TIA导入”按钮。
|
||||||
|
/// </summary>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async void ImprotFromTiaVarTable()
|
private async void ImprotFromTiaVarTable()
|
||||||
{
|
{
|
||||||
ContentDialog processingDialog = null;
|
ContentDialog processingDialog = null; // 用于显示处理中的对话框
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 让用户选择导入的Excel文件
|
// 让用户选择要导入的Excel文件路径
|
||||||
var filePath = await _dialogService.ShowImportExcelDialog();
|
var filePath = await _dialogService.ShowImportExcelDialog();
|
||||||
if (string.IsNullOrEmpty(filePath))
|
if (string.IsNullOrEmpty(filePath))
|
||||||
return;
|
return; // 如果用户取消选择,则返回
|
||||||
// 读取Excel转换成VariableData列表
|
|
||||||
|
// 读取Excel文件并将其内容转换为 VariableData 列表
|
||||||
var importVarDataList = ExcelHelper.ImprotFromTiaVariableTable(filePath);
|
var importVarDataList = ExcelHelper.ImprotFromTiaVariableTable(filePath);
|
||||||
if (importVarDataList.Count == 0)
|
if (importVarDataList.Count == 0)
|
||||||
return;
|
return; // 如果没有读取到数据,则返回
|
||||||
processingDialog= _dialogService.ShowProcessingDialog("正在处理...", "正在导入变量,请稍等片刻....");
|
|
||||||
|
|
||||||
|
// 显示处理中的对话框
|
||||||
|
processingDialog = _dialogService.ShowProcessingDialog("正在处理...", "正在导入变量,请稍等片刻....");
|
||||||
|
|
||||||
|
// 为导入的每个变量设置创建时间和所属变量表ID
|
||||||
foreach (var variableData in importVarDataList)
|
foreach (var variableData in importVarDataList)
|
||||||
{
|
{
|
||||||
variableData.CreateTime=DateTime.Now;
|
variableData.CreateTime = DateTime.Now;
|
||||||
variableData.VariableTableId = VariableTable.Id;
|
variableData.VariableTableId = VariableTable.Id;
|
||||||
}
|
}
|
||||||
// 插入数据库
|
|
||||||
var resVarDataCount= await _varDataRepository.AddAsync(importVarDataList);
|
|
||||||
//更新界面
|
|
||||||
// variableTable.DataVariables.AddRange(resVarDataList);
|
|
||||||
variableTable.DataVariables= await _varDataRepository.GetAllAsync();
|
|
||||||
_dataVariables=new ObservableCollection<VariableData>(variableTable.DataVariables);
|
|
||||||
processingDialog?.Hide();
|
|
||||||
|
|
||||||
|
// 批量插入变量数据到数据库
|
||||||
|
var resVarDataCount = await _varDataRepository.AddAsync(importVarDataList);
|
||||||
|
|
||||||
|
// 更新界面显示的数据:重新从数据库加载所有变量数据
|
||||||
|
await RefreshDataView();
|
||||||
|
|
||||||
|
processingDialog?.Hide(); // 隐藏处理中的对话框
|
||||||
|
|
||||||
|
// 显示成功通知并记录日志
|
||||||
string msgSuccess = $"成功导入变量:{resVarDataCount}个。";
|
string msgSuccess = $"成功导入变量:{resVarDataCount}个。";
|
||||||
NlogHelper.Info(msgSuccess);
|
NlogHelper.Info(msgSuccess);
|
||||||
NotificationHelper.ShowSuccess(msgSuccess);
|
NotificationHelper.ShowSuccess(msgSuccess);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
// 捕获并显示错误通知
|
||||||
NotificationHelper.ShowError($"从TIA导入变量的过程中发生了不可预期的错误:{e.Message}", e);
|
NotificationHelper.ShowError($"从TIA导入变量的过程中发生了不可预期的错误:{e.Message}", e);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
processingDialog?.Hide(); // 确保在任何情况下都隐藏对话框
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从OPC UA服务器导入变量数据。
|
||||||
|
/// 此命令通常绑定到UI中的“从OPC UA导入”按钮。
|
||||||
|
/// </summary>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task ImportFromOpcUaServer()
|
private async Task ImportFromOpcUaServer()
|
||||||
{
|
{
|
||||||
|
ContentDialog processingDialog = null; // 用于显示处理中的对话框
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 检查OPC UA Endpoint URL是否已设置
|
||||||
string opcUaEndpointUrl = VariableTable?.Device?.OpcUaEndpointUrl;
|
string opcUaEndpointUrl = VariableTable?.Device?.OpcUaEndpointUrl;
|
||||||
if (string.IsNullOrEmpty(opcUaEndpointUrl))
|
if (string.IsNullOrEmpty(opcUaEndpointUrl))
|
||||||
{
|
{
|
||||||
NotificationHelper.ShowError("OPC UA Endpoint URL 未设置。请在设备详情中配置。");
|
NotificationHelper.ShowError("OPC UA Endpoint URL 未设置。请在设备详情中配置。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示OPC UA导入对话框,让用户选择要导入的变量
|
||||||
var importedVariables = await _dialogService.ShowOpcUaImportDialog(opcUaEndpointUrl);
|
var importedVariables = await _dialogService.ShowOpcUaImportDialog(opcUaEndpointUrl);
|
||||||
if (importedVariables == null || !importedVariables.Any())
|
if (importedVariables == null || !importedVariables.Any())
|
||||||
{
|
{
|
||||||
return; // 用户取消或没有选择任何变量
|
return; // 用户取消或没有选择任何变量
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentDialog processingDialog = _dialogService.ShowProcessingDialog("正在处理...", "正在导入OPC UA变量,请稍等片刻....");
|
// 显示处理中的对话框
|
||||||
|
processingDialog = _dialogService.ShowProcessingDialog("正在处理...", "正在导入OPC UA变量,请稍等片刻....");
|
||||||
|
|
||||||
|
// 为导入的每个变量设置创建时间、所属变量表ID和协议类型
|
||||||
foreach (var variableData in importedVariables)
|
foreach (var variableData in importedVariables)
|
||||||
{
|
{
|
||||||
variableData.CreateTime = DateTime.Now;
|
variableData.CreateTime = DateTime.Now;
|
||||||
variableData.VariableTableId = VariableTable.Id;
|
variableData.VariableTableId = VariableTable.Id;
|
||||||
variableData.ProtocolType = ProtocolType.OpcUA; // 确保协议类型正确
|
variableData.ProtocolType = ProtocolType.OpcUA; // 确保协议类型正确
|
||||||
|
variableData.IsModified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入数据库
|
// 批量插入变量数据到数据库
|
||||||
var resVarDataCount = await _varDataRepository.AddAsync(importedVariables);
|
var resVarDataCount = await _varDataRepository.AddAsync(importedVariables);
|
||||||
|
|
||||||
// 更新界面
|
await RefreshDataView();
|
||||||
variableTable.DataVariables = await _varDataRepository.GetAllAsync();
|
|
||||||
_dataVariables = new ObservableCollection<VariableData>(variableTable.DataVariables);
|
|
||||||
processingDialog?.Hide();
|
|
||||||
|
|
||||||
|
processingDialog?.Hide(); // 隐藏处理中的对话框
|
||||||
|
|
||||||
|
// 显示成功通知并记录日志
|
||||||
string msgSuccess = $"成功导入OPC UA变量:{resVarDataCount}个。";
|
string msgSuccess = $"成功导入OPC UA变量:{resVarDataCount}个。";
|
||||||
NlogHelper.Info(msgSuccess);
|
|
||||||
NotificationHelper.ShowSuccess(msgSuccess);
|
NotificationHelper.ShowSuccess(msgSuccess);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
// 捕获并显示错误通知
|
||||||
NotificationHelper.ShowError($"从OPC UA服务器导入变量的过程中发生了不可预期的错误:{e.Message}", e);
|
NotificationHelper.ShowError($"从OPC UA服务器导入变量的过程中发生了不可预期的错误:{e.Message}", e);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
processingDialog?.Hide(); // 确保在任何情况下都隐藏对话框
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 刷新数据列表
|
||||||
|
/// </summary>
|
||||||
|
private async Task RefreshDataView()
|
||||||
|
{
|
||||||
|
// 更新界面显示的数据:重新从数据库加载所有变量数据
|
||||||
|
VariableTable.DataVariables = await _varDataRepository.GetByVariableTableId(VariableTable.Id);
|
||||||
|
DataVariables.Clear();
|
||||||
|
foreach (var item in VariableTable.DataVariables)
|
||||||
|
{
|
||||||
|
DataVariables.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
VariableDataView.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加新的变量数据。
|
||||||
|
/// 此命令通常绑定到UI中的“添加”按钮。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableTable">当前操作的变量表,用于设置新变量的所属ID。</param>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async void AddVarData(VariableTable variableTable)
|
private async void AddVarData(VariableTable variableTable)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// // 1. 显示添加设备对话框
|
// 显示添加变量数据的对话框
|
||||||
var varData = await _dialogService.ShowAddVarDataDialog();
|
var varData = await _dialogService.ShowAddVarDataDialog();
|
||||||
// // 如果用户取消或对话框未返回设备,则直接返回
|
|
||||||
|
// 如果用户取消或对话框未返回数据,则直接返回
|
||||||
if (varData == null)
|
if (varData == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// 设置新变量的所属变量表ID
|
||||||
varData.VariableTableId = variableTable.Id;
|
varData.VariableTableId = variableTable.Id;
|
||||||
// 更新数据库
|
|
||||||
|
// 添加变量数据到数据库
|
||||||
await _varDataRepository.AddAsync(varData);
|
await _varDataRepository.AddAsync(varData);
|
||||||
// 更新当前页面的
|
|
||||||
_dataVariables.Add(varData);
|
// 更新当前页面显示的数据:将新变量添加到集合中
|
||||||
|
DataVariables.Add(varData);
|
||||||
|
|
||||||
|
// 显示成功通知
|
||||||
NotificationHelper.ShowSuccess($"添加变量成功:{varData?.Name}");
|
NotificationHelper.ShowSuccess($"添加变量成功:{varData?.Name}");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
// 捕获并显示错误通知
|
||||||
NotificationHelper.ShowError($"添加变量的过程中发生了不可预期的错误:{e.Message}", e);
|
NotificationHelper.ShowError($"添加变量的过程中发生了不可预期的错误:{e.Message}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除选定的变量数据。
|
||||||
|
/// 此命令通常绑定到UI中的“删除”按钮。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variablesToDelete">要删除的变量数据列表。</param>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task DeleteVarData(List<VariableData> variablesToDelete)
|
public async Task DeleteVarData(List<VariableData> variablesToDelete)
|
||||||
{
|
{
|
||||||
|
// 检查是否有变量被选中
|
||||||
if (variablesToDelete == null || !variablesToDelete.Any())
|
if (variablesToDelete == null || !variablesToDelete.Any())
|
||||||
{
|
{
|
||||||
NotificationHelper.ShowInfo("请选择要删除的变量");
|
NotificationHelper.ShowInfo("请选择要删除的变量");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 拼接要删除的变量名称,用于确认提示
|
||||||
var names = string.Join("、", variablesToDelete.Select(v => v.Name));
|
var names = string.Join("、", variablesToDelete.Select(v => v.Name));
|
||||||
|
|
||||||
|
// 显示确认删除对话框
|
||||||
var confirm = await _dialogService.ShowConfrimeDialog(
|
var confirm = await _dialogService.ShowConfrimeDialog(
|
||||||
"删除确认",
|
"删除确认",
|
||||||
$"确定要删除选中的 {variablesToDelete.Count} 个变量吗?\n\n{names}",
|
$"确定要删除选中的 {variablesToDelete.Count} 个变量吗?\n\n{names}",
|
||||||
"删除");
|
"删除");
|
||||||
|
|
||||||
if (!confirm)
|
if (!confirm)
|
||||||
return;
|
return; // 如果用户取消删除,则返回
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 从数据库中删除变量数据
|
||||||
var result = await _varDataRepository.DeleteAsync(variablesToDelete);
|
var result = await _varDataRepository.DeleteAsync(variablesToDelete);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
{
|
{
|
||||||
foreach (var variable in variablesToDelete)
|
await RefreshDataView();
|
||||||
{
|
// 显示成功通知
|
||||||
_dataVariables.Remove(variable);
|
|
||||||
}
|
|
||||||
NotificationHelper.ShowSuccess($"成功删除 {result} 个变量");
|
NotificationHelper.ShowSuccess($"成功删除 {result} 个变量");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 显示删除失败通知
|
||||||
NotificationHelper.ShowError("删除变量失败");
|
NotificationHelper.ShowError("删除变量失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
// 捕获并显示错误通知
|
||||||
NotificationHelper.ShowError($"删除变量的过程中发生了不可预期的错误:{e.Message}", e);
|
NotificationHelper.ShowError($"删除变量的过程中发生了不可预期的错误:{e.Message}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更改选定变量的轮询频率。
|
||||||
|
/// 此命令通常绑定到UI中的“修改轮询频率”按钮。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variablesToChange">要修改轮询频率的变量数据列表。</param>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task ChangePollLevel(List<VariableData> variablesToChange)
|
public async Task ChangePollLevel(List<VariableData> variablesToChange)
|
||||||
{
|
{
|
||||||
|
// 检查是否有变量被选中
|
||||||
if (variablesToChange == null || !variablesToChange.Any())
|
if (variablesToChange == null || !variablesToChange.Any())
|
||||||
{
|
{
|
||||||
NotificationHelper.ShowInfo("请选择要修改轮询频率的变量");
|
NotificationHelper.ShowInfo("请选择要修改轮询频率的变量");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newPollLevelType = await _dialogService.ShowPollLevelDialog(variablesToChange.First().PollLevelType);
|
// 显示轮询频率选择对话框,并传入第一个变量的当前轮询频率作为默认值
|
||||||
|
var newPollLevelType = await _dialogService.ShowPollLevelDialog(variablesToChange.First()
|
||||||
|
.PollLevelType);
|
||||||
if (newPollLevelType.HasValue)
|
if (newPollLevelType.HasValue)
|
||||||
{
|
{
|
||||||
|
// 更新所有选定变量的轮询频率和修改状态
|
||||||
foreach (var variable in variablesToChange)
|
foreach (var variable in variablesToChange)
|
||||||
{
|
{
|
||||||
variable.PollLevelType = newPollLevelType.Value;
|
variable.PollLevelType = newPollLevelType.Value;
|
||||||
variable.IsModified=false;
|
variable.IsModified = false; // 标记为未修改,因为已保存到数据库
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量更新数据库中的变量数据
|
||||||
await _varDataRepository.UpdateAsync(variablesToChange);
|
await _varDataRepository.UpdateAsync(variablesToChange);
|
||||||
|
// 显示成功通知
|
||||||
NotificationHelper.ShowSuccess($"已成功更新 {variablesToChange.Count} 个变量的轮询频率");
|
NotificationHelper.ShowSuccess($"已成功更新 {variablesToChange.Count} 个变量的轮询频率");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为选定的变量添加MQTT服务器。
|
||||||
|
/// 此命令通常绑定到UI中的“添加MQTT服务器”按钮。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variablesToAddMqtt">要添加MQTT服务器的变量数据列表。</param>
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task AddMqttServerToVariables(IList<VariableData> variablesToAddMqtt)
|
public async Task AddMqttServerToVariables(IList<VariableData> variablesToAddMqtt)
|
||||||
{
|
{
|
||||||
|
// 检查是否有变量被选中
|
||||||
if (variablesToAddMqtt == null || !variablesToAddMqtt.Any())
|
if (variablesToAddMqtt == null || !variablesToAddMqtt.Any())
|
||||||
{
|
{
|
||||||
NotificationHelper.ShowInfo("请选择要添加MQTT服务器的变量");
|
NotificationHelper.ShowInfo("请选择要添加MQTT服务器的变量");
|
||||||
@@ -370,60 +583,62 @@ partial class VariableTableViewModel : ViewModelBase
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 显示MQTT服务器选择对话框,让用户选择一个MQTT服务器
|
||||||
var selectedMqtt = await _dialogService.ShowMqttSelectionDialog();
|
var selectedMqtt = await _dialogService.ShowMqttSelectionDialog();
|
||||||
if (selectedMqtt == null)
|
if (selectedMqtt == null)
|
||||||
{
|
{
|
||||||
return; // 用户取消选择
|
return; // 用户取消选择
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 遍历所有选定的变量,并为其添加选定的MQTT服务器
|
||||||
foreach (VariableData variable in variablesToAddMqtt)
|
foreach (VariableData variable in variablesToAddMqtt)
|
||||||
{
|
{
|
||||||
|
// 如果变量的Mqtts集合为空,则初始化它
|
||||||
if (variable.Mqtts == null)
|
if (variable.Mqtts == null)
|
||||||
{
|
{
|
||||||
variable.Mqtts = new List<Mqtt>();
|
variable.Mqtts = new List<Mqtt>();
|
||||||
}
|
}
|
||||||
// 避免重复添加
|
|
||||||
|
// 避免重复添加相同的MQTT服务器
|
||||||
if (!variable.Mqtts.Any(m => m.Id == selectedMqtt.Id))
|
if (!variable.Mqtts.Any(m => m.Id == selectedMqtt.Id))
|
||||||
{
|
{
|
||||||
variable.Mqtts.Add(selectedMqtt);
|
variable.Mqtts.Add(selectedMqtt);
|
||||||
// variable.IsModified = true; // 标记为已修改
|
// variable.IsModified = true; // 标记为已修改 (如果需要UI立即反映,但此处批量更新数据库,所以可以省略)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量更新数据库
|
// 批量更新数据库中的变量数据
|
||||||
await _varDataRepository.UpdateAsync(variablesToAddMqtt.ToList());
|
await _varDataRepository.UpdateAsync(variablesToAddMqtt.ToList());
|
||||||
|
// 显示成功通知
|
||||||
NotificationHelper.ShowSuccess($"已成功为 {variablesToAddMqtt.Count} 个变量添加MQTT服务器: {selectedMqtt.Name}");
|
NotificationHelper.ShowSuccess($"已成功为 {variablesToAddMqtt.Count} 个变量添加MQTT服务器: {selectedMqtt.Name}");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
// 捕获并显示错误通知
|
||||||
NotificationHelper.ShowError($"添加MQTT服务器失败: {ex.Message}", ex);
|
NotificationHelper.ShowError($"添加MQTT服务器失败: {ex.Message}", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RelayCommand]
|
/// <summary>
|
||||||
// private async void ImportFromExcel()
|
/// 当变量表的启用/禁用状态改变时调用。
|
||||||
// {
|
/// 更新数据库中变量表的激活状态,并显示相应的通知。
|
||||||
// var filePath = await _dialogService.ShowImportExcelDialog();
|
/// </summary>
|
||||||
// if (!string.IsNullOrEmpty(filePath))
|
/// <param name="active">变量表的新激活状态(true为启用,false为禁用)。</param>
|
||||||
// {
|
|
||||||
// // TODO: Implement Excel import logic using the filePath
|
|
||||||
// NotificationHelper.ShowMessage($"Successfully imported from {filePath}", NotificationType.Success);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
public async Task OnIsActiveChanged(bool active)
|
public async Task OnIsActiveChanged(bool active)
|
||||||
{
|
{
|
||||||
|
// 更新数据库中变量表的激活状态
|
||||||
var res = await _varTableRepository.Edit(VariableTable);
|
var res = await _varTableRepository.Edit(VariableTable);
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
{
|
{
|
||||||
|
// 根据激活状态显示成功通知
|
||||||
var statusMessage = active ? "已启用" : "已停用";
|
var statusMessage = active ? "已启用" : "已停用";
|
||||||
NotificationHelper.ShowSuccess($"变量表:{VariableTable.Name},{statusMessage}");
|
NotificationHelper.ShowSuccess($"变量表:{VariableTable.Name},{statusMessage}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 显示失败通知
|
||||||
NotificationHelper.ShowError($"变量表:{VariableTable.Name},状态修改失败,状态:{active}");
|
NotificationHelper.ShowError($"变量表:{VariableTable.Name},状态修改失败,状态:{active}");
|
||||||
// _logger.LogInformation($"变量表:{VariableTable.Name},状态修改失败,状态:{active}");
|
// _logger.LogInformation($"变量表:{VariableTable.Name},状态修改失败,状态:{active}"); // 可以选择记录日志
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user