WPF-UI库页面导航时如何传递DataMod数据?
基于共享服务的WPF-UI导航传参方案
针对WPF-UI库INavigationAware不支持直接传参的问题,用全局共享参数服务是MVVM场景下高效且解耦的方案,完全匹配你的业务流程,具体实现如下:
1. 定义共享参数服务
先写一个线程安全的参数存储服务,负责暂存和读取导航参数:
public interface INavigationParameterService { // 存入参数,支持自定义key区分不同参数类型 void SetParameter<T>(T parameter, string key = "default"); // 读取并自动清空参数,避免残留旧数据 T GetParameter<T>(string key = "default"); // 手动清空指定key的参数 void ClearParameter(string key = "default"); } public class NavigationParameterService : INavigationParameterService { private readonly Dictionary<string, object> _parameterStore = new(); private readonly object _lockObj = new(); public void SetParameter<T>(T parameter, string key = "default") { lock (_lockObj) { if (_parameterStore.ContainsKey(key)) _parameterStore[key] = parameter; else _parameterStore.Add(key, parameter); } } public T GetParameter<T>(string key = "default") { lock (_lockObj) { if (_parameterStore.TryGetValue(key, out var param) && param is T typedParam) { ClearParameter(key); return typedParam; } return default; } } public void ClearParameter(string key = "default") { lock (_lockObj) { _parameterStore.Remove(key); } } }
2. 在导航发起方(ModRepositoryViewModel)中使用服务
点击模组按钮时,先将DataMod存入服务,再触发导航:
public class ModRepositoryViewModel : ViewModelBase { private readonly INavigationParameterService _paramService; private readonly INavigationService _navigationService; // 绑定按钮的命令,参数为选中的DataMod public ICommand NavigateToModPageCommand { get; } public ModRepositoryViewModel(INavigationParameterService paramService, INavigationService navigationService) { _paramService = paramService; _navigationService = navigationService; NavigateToModPageCommand = new RelayCommand<DataMod>(ExecuteNavigation); } private void ExecuteNavigation(DataMod selectedMod) { if (selectedMod == null) return; // 存入选中的模组数据 _paramService.SetParameter(selectedMod); // 导航到ModPage(页面类型或WPF-UI定义的导航Key) _navigationService.Navigate(typeof(ModPage)); } }
3. 在目标页(ModPageViewModel)中读取参数
实现INavigationAware接口,在页面导航进入时从服务取出参数并绑定到UI:
public class ModPageViewModel : ViewModelBase, INavigationAware { private readonly INavigationParameterService _paramService; private DataMod _currentMod; // 绑定UI的属性 public DataMod CurrentMod { get => _currentMod; set => SetProperty(ref _currentMod, value); } public ModPageViewModel(INavigationParameterService paramService) { _paramService = paramService; } public void OnNavigatedTo() { // 读取参数并赋值给绑定属性 var receivedMod = _paramService.GetParameter<DataMod>(); if (receivedMod != null) { CurrentMod = receivedMod; // 这里可以添加模组数据的初始化逻辑 } } public void OnNavigatedFrom() { // 可选:离开页面时强制清空参数,防止内存泄漏 _paramService.ClearParameter(); } }
4. 注册服务到DI容器
在应用启动时将参数服务注册为单例,确保全局共享同一个实例:
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { // 以Autofac为例,其他DI容器逻辑类似 var containerBuilder = new ContainerBuilder(); // 注册单例参数服务 containerBuilder.RegisterType<NavigationParameterService>() .As<INavigationParameterService>() .SingleInstance(); // 注册其他ViewModel和服务 containerBuilder.RegisterType<ModRepositoryViewModel>(); containerBuilder.RegisterType<ModPageViewModel>(); var container = containerBuilder.Build(); // 绑定ViewModel定位器,让WPF-UI能自动解析ViewModel ViewModelLocator.SetDefaultViewModelFactory(type => container.Resolve(type)); base.OnStartup(e); } }
关键注意事项
- 服务用
SingleInstance注册,保证参数在全局唯一的实例中传递。 - 读取参数后自动清空,避免多次导航时拿到旧数据,同时防止内存泄漏。
- 如果需要传递多种类型参数,可通过自定义
key区分(比如SetParameter(mod, "SelectedMod"))。
内容的提问来源于stack exchange,提问作者szaamerik
相关产品推荐
相关产品推荐

