实现导航跳转

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

@@ -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;