You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:43:18