实现导航跳转

This commit is contained in:
2025-07-30 12:09:00 +08:00
parent 3b5ecef895
commit 1ebc1a4df6
21 changed files with 150 additions and 248 deletions

View File

@@ -13,25 +13,6 @@ public class MappingProfile : Profile
{
// // Device 映射
// CreateMap<UpdateDeviceDto, Device>()
// // 1. 首先忽略那些永远不应从DTO更新的属性
// .ForMember(dest => dest.Id, opt => opt.Ignore())
// .ForMember(dest => dest.Description, opt => opt.Ignore())
// .ForMember(dest => dest.VariableTables, opt => opt.Ignore())
// .ForMember(dest => dest.CpuType, opt => opt.Ignore())
// .ForMember(dest => dest.IsRunning, opt => opt.Ignore())
// .ForMember(dest => dest.DeviceType, opt => opt.Ignore())
//
// // 2. 然后,为每个可空属性单独设置条件
// .ForMember(dest => dest.Name, opt => opt.Condition(src => src.Name != null))
// .ForMember(dest => dest.Protocol, opt => opt.Condition(src => src.Protocol.HasValue))
// .ForMember(dest => dest.IpAddress, opt => opt.Condition(src => src.IpAddress != null))
// .ForMember(dest => dest.Port, opt => opt.Condition(src => src.Port.HasValue))
// .ForMember(dest => dest.Rack, opt => opt.Condition(src => src.Rack.HasValue))
// .ForMember(dest => dest.Slot, opt => opt.Condition(src => src.Slot.HasValue))
// .ForMember(dest => dest.OpcUaServerUrl, opt => opt.Condition(src => src.OpcUaServerUrl != null))
// .ForMember(dest => dest.IsActive, opt => opt.Condition(src => src.IsActive.HasValue));
CreateMap<Device, DeviceDto>()
.ReverseMap();

View File

@@ -11,10 +11,10 @@ namespace DMS.WPF.Profiles
CreateMap<DeviceDto, DeviceItemViewModel>()
.ReverseMap();
CreateMap<MenuBeanDto, MenuBeanItemViewModel>()
CreateMap<MenuBeanDto, MenuItemViewModel>()
.ForMember(dest => dest.Children, opt => opt.Ignore())
.ConstructUsing(src => new MenuBeanItemViewModel(
src, null)); // 假设 NavigationService 可以通过依赖注入获取或在ViewModel中处理
.ReverseMap();
CreateMap<MqttServerDto, MqttServerItemViewModel>().ReverseMap();
CreateMap<UserDto, UserItemViewModel>().ReverseMap();
CreateMap<VariableHistoryDto, VariableHistoryItemViewModel>().ReverseMap();

View File

@@ -44,11 +44,11 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
// 菜单树列表。
[ObservableProperty]
private ObservableCollection<MenuBeanItemViewModel> _menus;
private ObservableCollection<MenuItemViewModel> _menus;
// 菜单树列表。
[ObservableProperty]
private ObservableCollection<MenuBeanItemViewModel> _menuTrees;
private ObservableCollection<MenuItemViewModel> _menuTrees;
// MQTT配置列表。
// [ObservableProperty]
@@ -93,8 +93,8 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
Devices = new ObservableCollection<DeviceItemViewModel>();
VariableTables = new ObservableCollection<VariableTableItemViewModel>();
Variables = new ObservableCollection<VariableItemViewModel>();
Menus = new ObservableCollection<MenuBeanItemViewModel>();
MenuTrees = new ObservableCollection<MenuBeanItemViewModel>();
Menus = new ObservableCollection<MenuItemViewModel>();
MenuTrees = new ObservableCollection<MenuItemViewModel>();
// AllVariables = new ConcurrentDictionary<int, Variable>();
}
@@ -165,7 +165,7 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
var newMenuIds = new HashSet<int>(newMenus.Select(m => m.Id));
// 1. 更新现有项 & 查找需要删除的项
var itemsToRemove = new List<MenuBeanItemViewModel>();
var itemsToRemove = new List<MenuItemViewModel>();
foreach (var existingItem in Menus)
{
if (newMenuIds.Contains(existingItem.Id))
@@ -177,12 +177,7 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
// 注意MenuItemViewModel 的属性是 ObservableProperty直接赋值会触发通知
if (existingItem.Header != newDto.Header) existingItem.Header = newDto.Header;
if (existingItem.Icon != newDto.Icon) existingItem.Icon = newDto.Icon;
// 对于 TargetViewKey 和 NavigationParameter它们在 MenuItemViewModel 中是私有字段,
// 并且在构造时通过 INavigationService 绑定到 NavigateCommand。
// 如果这些需要动态更新MenuItemViewModel 内部需要提供公共属性或方法来处理。
// 目前我们假设如果这些变化IMenuService 会返回一个新的 MenuItemViewModel 实例。
// 如果需要更细粒度的更新,需要修改 MenuItemViewModel 的设计。
// 这里我们只更新直接暴露的 ObservableProperty。
}
else
{
@@ -205,7 +200,7 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
{
// 这是一个新菜单项,添加到集合中
// 注意:这里直接添加 IMenuService 返回的 MenuItemViewModel 实例
Menus.Add(new MenuBeanItemViewModel(newDto, _navigationService));
Menus.Add(_mapper.Map<MenuItemViewModel>(newDto));
}
}
@@ -470,18 +465,18 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
}
}
public void AddMenuItem(MenuBeanItemViewModel menuBeanItemViewModel)
public void AddMenuItem(MenuItemViewModel menuItemViewModel)
{
if (menuBeanItemViewModel == null)
if (menuItemViewModel == null)
{
return;
}
var deviceMenu = Menus.FirstOrDefault(m => m.Id == menuBeanItemViewModel.ParentId);
var deviceMenu = Menus.FirstOrDefault(m => m.Id == menuItemViewModel.ParentId);
if (deviceMenu != null)
{
deviceMenu.Children.Add(menuBeanItemViewModel);
Menus.Add(menuBeanItemViewModel);
deviceMenu.Children.Add(menuItemViewModel);
Menus.Add(menuItemViewModel);
}
}
@@ -498,27 +493,27 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
}
}
public void DeleteMenuItem(MenuBeanItemViewModel menuBeanItemViewModel)
public void DeleteMenuItem(MenuItemViewModel menuItemViewModel)
{
if (menuBeanItemViewModel == null)
if (menuItemViewModel == null)
{
return;
}
// 从扁平菜单列表中移除
Menus.Remove(menuBeanItemViewModel);
Menus.Remove(menuItemViewModel);
// 从树形结构中移除
if (menuBeanItemViewModel.ParentId.HasValue && menuBeanItemViewModel.ParentId.Value != 0)
if (menuItemViewModel.ParentId.HasValue && menuItemViewModel.ParentId.Value != 0)
{
// 如果有父菜单从父菜单的Children中移除
var parentMenu = Menus.FirstOrDefault(m => m.Id == menuBeanItemViewModel.ParentId.Value);
parentMenu?.Children.Remove(menuBeanItemViewModel);
var parentMenu = Menus.FirstOrDefault(m => m.Id == menuItemViewModel.ParentId.Value);
parentMenu?.Children.Remove(menuItemViewModel);
}
else
{
// 如果是根菜单从MenuTrees中移除
MenuTrees.Remove(menuBeanItemViewModel);
MenuTrees.Remove(menuItemViewModel);
}
}

View File

@@ -1,4 +1,7 @@
// 文件: DMS.WPF/Services/INavigatable.cs
using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.Services;
/// <summary>
@@ -10,5 +13,5 @@ public interface INavigatable
/// 当导航到此ViewModel时由导航服务调用此方法以传递参数。
/// </summary>
/// <param name="parameter">从导航源传递过来的参数对象。</param>
Task OnNavigatedToAsync(object parameter);
Task OnNavigatedToAsync(MenuItemViewModel menu);
}

View File

@@ -1,5 +1,6 @@
// 文件: DMS.WPF/Services/INavigationService.cs
using System.Threading.Tasks;
using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.Services;
@@ -13,6 +14,6 @@ public interface INavigationService
/// </summary>
/// <param name="viewKey">在DI容器中注册的目标视图的唯一键通常是ViewModel的名称。</param>
/// <param name="parameter">要传递给目标ViewModel的参数。</param>
Task NavigateToAsync(string viewKey, object parameter = null);
Task NavigateToAsync(MenuItemViewModel menu);
}

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using DMS.ViewModels;
using DMS.WPF.ViewModels.Items;
using DMS.WPF.Views;
namespace DMS.WPF.Services;
@@ -29,19 +30,19 @@ public class NavigationService : INavigationService
/// <summary>
/// 导航到指定键的视图,并传递参数。
/// </summary>
public async Task NavigateToAsync(string viewKey, object parameter = null)
public async Task NavigateToAsync(MenuItemViewModel menu)
{
if (string.IsNullOrEmpty(viewKey))
if (string.IsNullOrEmpty(menu.TargetViewKey))
{
return;
}
var mainViewModel = App.Current.Services.GetRequiredService<MainViewModel>();
var viewModel = GetViewModelByKey(viewKey);
var viewModel = GetViewModelByKey(menu.TargetViewKey);
if (viewModel is INavigatable navigatableViewModel)
{
await navigatableViewModel.OnNavigatedToAsync(parameter);
await navigatableViewModel.OnNavigatedToAsync(menu);
}
mainViewModel.CurrentViewModel = viewModel;

View File

@@ -1,15 +1,17 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.Core.Enums;
using DMS.WPF.Services;
using DMS.Services;
using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.ViewModels;
public partial class DeviceDetailViewModel : ViewModelBase
public partial class DeviceDetailViewModel : ViewModelBase,INavigatable
{
private readonly IDialogService _dialogService;
private readonly DataServices _dataServices;
private readonly INavigationService _navigationService;
public DataServices DataServices { get; set; }
[ObservableProperty]
private DeviceItemViewModel _currentDevice;
@@ -17,10 +19,11 @@ public partial class DeviceDetailViewModel : ViewModelBase
[ObservableProperty]
private VariableItemViewModel _selectedVariableTable;
public DeviceDetailViewModel(IDialogService dialogService, DataServices dataServices)
public DeviceDetailViewModel(IDialogService dialogService,INavigationService navigationService, DataServices dataServices)
{
_dialogService = dialogService;
_dataServices = dataServices;
_navigationService = navigationService;
DataServices = dataServices;
}
public override void OnLoaded()
@@ -95,11 +98,11 @@ public partial class DeviceDetailViewModel : ViewModelBase
[RelayCommand]
private async Task EditVariableTable()
{
// if (SelectedVariableTable == null)
// {
// //NotificationHelper.ShowInfo("请选择要编辑的变量表。");
// return;
// }
if (SelectedVariableTable == null)
{
// NotificationHelper.ShowInfo("请选择要编辑的变量表。");
return;
}
//
// using var db = DbContext.GetInstance();
// try
@@ -218,13 +221,23 @@ public partial class DeviceDetailViewModel : ViewModelBase
await Task.CompletedTask;
}
[RelayCommand]
private void NavigateToVariableTable()
public async Task OnNavigatedToAsync(MenuItemViewModel menu)
{
// if (SelectedVariableTable == null) return;
//
// var variableTableVm = App.Current.Services.GetRequiredService<VariableTableViewModel>();
// variableTableVm.VariableTable = SelectedVariableTable;
// MessageHelper.SendNavgatorMessage(variableTableVm);
var device= DataServices.Devices.FirstOrDefault(d => d.Id == menu.TargetId);
if (device!=null)
{
CurrentDevice = device;
}
}
[RelayCommand]
public void NavigateToVariableTable()
{
if (SelectedVariableTable == null) return;
var menu=DataServices.Menus.FirstOrDefault(m => m.MenuType == MenuType.VariableTableMenu && m.TargetId == SelectedVariableTable.Id);
if (menu==null) return;
_navigationService.NavigateToAsync(menu);
}
}

View File

@@ -28,6 +28,7 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable
private readonly IDeviceAppService _deviceAppService;
private readonly IMapper _mapper;
private readonly IDialogService _dialogService;
private readonly INavigationService _navigationService;
/// <summary>
@@ -50,10 +51,12 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable
/// <param name="dialogService">对话框服务。</param>
/// <param name="dataServices">数据服务。</param>
public DevicesViewModel(IMapper mapper,
IDialogService dialogService, DataServices dataServices, IDeviceAppService deviceAppService)
IDialogService dialogService, INavigationService navigationService,
DataServices dataServices, IDeviceAppService deviceAppService)
{
_mapper = mapper;
_dialogService = dialogService;
_navigationService = navigationService;
DataServices = dataServices;
_deviceAppService = deviceAppService;
Devices = new ObservableCollection<DeviceItemViewModel>();
@@ -125,9 +128,9 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable
// 更新界面
DataServices.Devices.Add(_mapper.Map<DeviceItemViewModel>(addDto.Device));
DataServices.AddMenuItem(_mapper.Map<MenuBeanItemViewModel>(addDto.DeviceMenu));
DataServices.AddMenuItem(_mapper.Map<MenuItemViewModel>(addDto.DeviceMenu));
DataServices.AddVariableTable(_mapper.Map<VariableTableItemViewModel>(addDto.VariableTable));
DataServices.AddMenuItem(_mapper.Map<MenuBeanItemViewModel>(addDto.VariableTableMenu));
DataServices.AddMenuItem(_mapper.Map<MenuItemViewModel>(addDto.VariableTableMenu));
NotificationHelper.ShowSuccess($"设备添加成功:{addDto.Device.Name}");
}
@@ -224,12 +227,14 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable
public void NavigateToDetail()
{
if (SelectedDevice == null) return;
var deviceDetailVm = App.Current.Services.GetRequiredService<DeviceDetailViewModel>();
deviceDetailVm.CurrentDevice = SelectedDevice;
MessageHelper.SendNavgatorMessage(deviceDetailVm);
var menu=DataServices.Menus.FirstOrDefault(m => m.MenuType == MenuType.DeviceMenu && m.TargetId == SelectedDevice.Id);
if (menu==null) return;
_navigationService.NavigateToAsync(menu);
}
public async Task OnNavigatedToAsync(object parameter)
public async Task OnNavigatedToAsync(MenuItemViewModel menu)
{
}
}

View File

@@ -1,61 +0,0 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.Application.DTOs;
using DMS.Core.Enums;
using DMS.WPF.Services;
namespace DMS.WPF.ViewModels.Items;
public partial class MenuBeanItemViewModel : ObservableObject
{
public int Id { get; }
[ObservableProperty]
private int? _parentId;
[ObservableProperty]
private string _header;
[ObservableProperty]
private string _icon;
[ObservableProperty]
private MenuType _menuType;
[ObservableProperty]
private int _targetId;
[ObservableProperty]
private string _targetViewKey;
[ObservableProperty]
private string _navigationParameter;
[ObservableProperty]
private int _displayOrder;
[ObservableProperty]
private ObservableCollection<MenuBeanItemViewModel> _children=new ();
/// <summary>
/// 菜单项点击时执行的导航命令。
/// </summary>
public ICommand NavigateCommand { get; }
public MenuBeanItemViewModel(MenuBeanDto dto,INavigationService navigationService)
{
Id = dto.Id;
_parentId = dto.ParentId;
_header = dto.Header;
_icon = dto.Icon;
_menuType = dto.MenuType;
_targetViewKey=dto.TargetViewKey;
_targetId = dto.TargetId;
_navigationParameter = dto.NavigationParameter;
_displayOrder = dto.DisplayOrder;
NavigateCommand = new AsyncRelayCommand(async () =>
{
await navigationService.NavigateToAsync(_targetViewKey, _navigationParameter);
});
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.Application.DTOs;
using DMS.Core.Enums;
using DMS.WPF.Services;
namespace DMS.WPF.ViewModels.Items;
public partial class MenuItemViewModel : ObservableObject
{
public int Id { get; set; }
[ObservableProperty]
private int? _parentId;
[ObservableProperty]
private string _header;
[ObservableProperty]
private string _icon;
[ObservableProperty]
private MenuType _menuType;
[ObservableProperty]
private int _targetId;
[ObservableProperty]
private string _targetViewKey;
[ObservableProperty]
private string _navigationParameter;
[ObservableProperty]
private int _displayOrder;
[ObservableProperty]
private ObservableCollection<MenuItemViewModel> _children=new ();
}

View File

@@ -8,7 +8,7 @@ namespace DMS.WPF.ViewModels.Items;
public partial class MqttServerItemViewModel : ObservableObject
{
public int Id { get; }
public int Id { get; set; }
[ObservableProperty]
private string _serverName;

View File

@@ -5,7 +5,7 @@ namespace DMS.WPF.ViewModels.Items;
public partial class UserItemViewModel : ObservableObject
{
public int Id { get; }
public int Id { get; set; }
[ObservableProperty]
private string _username;

View File

@@ -6,7 +6,7 @@ namespace DMS.WPF.ViewModels.Items;
public partial class VariableHistoryItemViewModel : ObservableObject
{
public long Id { get; }
public long Id { get; set; }
[ObservableProperty]
private int _variableId;

View File

@@ -8,7 +8,7 @@ namespace DMS.WPF.ViewModels.Items;
public partial class VariableItemViewModel : ObservableObject
{
public int Id { get; }
public int Id { get; set; }
[ObservableProperty]
private string _name;

View File

@@ -5,7 +5,7 @@ namespace DMS.WPF.ViewModels.Items;
public partial class VariableMqttAliasItemViewModel : ObservableObject
{
public int Id { get; }
public int Id { get; set; }
[ObservableProperty]
private int _variableId;

View File

@@ -8,7 +8,7 @@ namespace DMS.WPF.ViewModels.Items;
public partial class VariableTableItemViewModel : ObservableObject
{
public int Id { get; }
public int Id { get; set; }
[ObservableProperty]
private string _name;

View File

@@ -164,64 +164,8 @@ public partial class MainViewModel : ViewModelBase
/// 处理菜单选择变化的逻辑。
/// </summary>
/// <param name="menu">被选中的菜单项。</param>
public async Task MenuSelectionChanged(MenuBeanItemViewModel menu)
public async Task MenuSelectionChanged(MenuItemViewModel menu)
{
_navigationService.NavigateToAsync(menu.TargetViewKey);
// try
// {
// switch (menu.Type)
// {
// // 导航到一级菜单
// case MenuType.MainMenu:
// menu.ViewModel = DataServicesHelper.GetMainViewModel(menu.Name);
// break;
// // 导航到设备下面的菜单
// case MenuType.DeviceMenu:
// var deviceDetailVm = App.Current.Services.GetRequiredService<DeviceDetailViewModel>();
// var currentDevice = _dataServices.Devices.FirstOrDefault(d => d.Id == menu.DataId);
// deviceDetailVm.CurrentDevice = currentDevice;
// menu.ViewModel = deviceDetailVm;
// menu.Data = currentDevice;
// break;
// // 导航到变量表菜单
// case MenuType.VariableTableMenu:
// VariableTableViewModel varTableVM =
// App.Current.Services.GetRequiredService<VariableTableViewModel>();
// varTableVM.VariableTable =
// DataServicesHelper.FindVarTableForDevice(_dataServices.Devices, menu.DataId);
//
// varTableVM.IsLoadCompletion = false;
// menu.ViewModel = varTableVM;
// menu.Data = varTableVM.VariableTable;
// break;
// // 导航到添加变量表的菜单
// case MenuType.AddVariableTableMenu:
// await AddVariableTable(menu);
// return;
// break;
// // 导航到Mqtt服务器
// case MenuType.MqttMenu:
// var mqttVM = App.Current.Services.GetRequiredService<MqttServerDetailViewModel>();
// mqttVM.CurrentMqtt = _dataServices.Mqtts.FirstOrDefault(d => d.Id == menu.DataId);
// menu.ViewModel = mqttVM;
// break;
// }
//
//
// if (menu.ViewModel != null)
// {
// MessageHelper.SendNavgatorMessage(menu.ViewModel);
// _logger.LogInformation($"导航到:{menu.Name}");
// }
// else
// {
// NotificationHelper.ShowInfo($"菜单:{menu.Name},没有对应的ViewModel.");
// _logger.LogInformation($"菜单:{menu.Name},没有对应的ViewModel.");
// }
// }
// catch (Exception e)
// {
// NotificationHelper.ShowError($"菜单切换时出现了错误:{e.Message}", e);
// }
_navigationService.NavigateToAsync(menu);
}
}

View File

@@ -16,39 +16,8 @@ using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.ViewModels;
/// <summary>
/// VariableTableViewModel 是用于管理和显示变量表数据的视图模型。
/// 它与 VariableTableView 视图进行数据绑定,并处理用户交互逻辑。
///
/// 调用逻辑概述:
/// 1. **实例化**: 当导航到 VariableTableView 时,通常会通过依赖注入框架(如 CommunityToolkit.Mvvm 的服务定位器或自定义工厂)实例化 VariableTableViewModel。
/// 构造函数 <see cref="VariableTableViewModel"/> 负责初始化必要的服务和数据仓库。
/// 2. **数据加载**:
/// - 当视图加载完成时,框架会自动调用 <see cref="OnLoaded"/> 方法。
/// - 此方法会根据传入的 <see cref="VariableTable"/> 对象初始化 <see cref="Variables"/> 集合,并设置协议类型相关的布尔属性。
/// - 它还会创建 <see cref="_originalVariables"/> 的深拷贝,用于在用户取消保存时还原数据。
/// 3. **数据绑定与显示**:
/// - <see cref="VariableTable"/> 属性绑定到视图中显示的当前变量表信息。
/// - <see cref="Variables"/> 属性ObservableCollection绑定到视图中的数据网格或列表用于显示变量数据。
/// - <see cref="VariableView"/> 是一个 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,INavigatable
{
private readonly IMapper _mapper;
@@ -62,7 +31,7 @@ partial class VariableTableViewModel : ViewModelBase
/// 通过 ObservableProperty 自动生成 VariableTable 属性和 OnVariableTableChanged 方法。
/// </summary>
[ObservableProperty]
private VariableItemViewModel variableTable;
private VariableTableItemViewModel currentVariableTable;
/// <summary>
/// 存储当前变量表中的所有变量数据的集合。
@@ -923,4 +892,14 @@ partial class VariableTableViewModel : ViewModelBase
// // _logger.LogInformation($"变量表:{VariableTable.Name},状态修改失败,状态:{active}"); // 可以选择记录日志
// }
}
public async Task OnNavigatedToAsync(MenuItemViewModel menu)
{
var varTable = _dataServices.VariableTables.FirstOrDefault(v => v.Id == menu.TargetId);
if (varTable!=null)
{
CurrentVariableTable=varTable;
}
}
}

View File

@@ -27,11 +27,11 @@
</i:Interaction.Triggers>
<ui:ContentDialog.Resources>
<ex:EnumBindingSource x:Key="deviceType"
<ex:EnumBindingSource x:Key="DeviceType"
EnumType="{x:Type enums:DeviceType}" />
<ex:EnumBindingSource x:Key="protocolType"
<ex:EnumBindingSource x:Key="ProtocolType"
EnumType="{x:Type enums:ProtocolType}" />
<ex:EnumBindingSource x:Key="cpuType"
<ex:EnumBindingSource x:Key="CpuType"
EnumType="{x:Type enums:CpuType}" />
<vc:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
<vc:EnumToStringConverter x:Key="EnumToStringConverter" />
@@ -68,7 +68,7 @@
<ComboBox
IsEnabled="{Binding IsAddMode}"
SelectedItem="{Binding Device.DeviceType}"
ItemsSource="{Binding Source={StaticResource deviceType} }">
ItemsSource="{Binding Source={StaticResource DeviceType} }">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}" />
@@ -107,7 +107,7 @@
<ComboBox x:Name="ProtocolComboBox"
IsEnabled="{Binding IsAddMode}"
SelectedItem="{Binding Device.Protocol}"
ItemsSource="{Binding Source={StaticResource protocolType} }">
ItemsSource="{Binding Source={StaticResource ProtocolType} }">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}" />
@@ -152,7 +152,7 @@
HorizontalAlignment="Left"
Style="{StaticResource TextBlockSubTitle}" />
<ComboBox SelectedItem="{Binding Device.CpuType}"
ItemsSource="{Binding Source={StaticResource cpuType}}" />
ItemsSource="{Binding Source={StaticResource CpuType}}" />
<!-- Rack -->
<TextBlock Text="机架号"

View File

@@ -59,7 +59,7 @@ public partial class MainView : Window
/// <param name="args"></param>
private async void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
var menu = args.SelectedItem as MenuBeanItemViewModel;
var menu = args.SelectedItem as MenuItemViewModel;
if (menu != null)
{
await _viewModel.MenuSelectionChanged(menu);

View File

@@ -131,23 +131,23 @@
OffContent="停用"
Toggled="OnIsActiveChanged"
FontSize="16"
IsOn="{Binding VariableTable.IsActive}" />
IsOn="{Binding CurrentVariableTable.IsActive}" />
<TextBlock Style="{StaticResource VarTableLabelStyle}"
Text="变量表名称:" />
<TextBlock Style="{StaticResource VarTableValueStyle}"
Text="{Binding VariableTable.Name}" />
Text="{Binding CurrentVariableTable.Name}" />
<TextBlock Style="{StaticResource VarTableLabelStyle}"
Text="变量表描述:" />
<TextBlock Style="{StaticResource VarTableValueStyle}"
Text="{Binding VariableTable.Description}" />
Text="{Binding CurrentVariableTable.Description}" />
<TextBlock Style="{StaticResource VarTableLabelStyle}"
Text="所属设备:" />
<TextBlock Style="{StaticResource VarTableValueStyle}"
Text="{Binding VariableTable.Device.Name}" />
Text="{Binding CurrentVariableTable.Device.Name}" />
<TextBlock Style="{StaticResource VarTableLabelStyle}"
Text="协议:" />
<TextBlock Style="{StaticResource VarTableValueStyle}"
Text="{Binding VariableTable.ProtocolType}" />
Text="{Binding CurrentVariableTable.Protocol}" />
<TextBlock Style="{StaticResource VarTableLabelStyle}"
Text="搜索:" />
<TextBox Width="200"