Prism_05_ViewModelLocator

ViewModelLocator 用于把 ViewModel 实例绑定到 View 的 DataContext.

解析ViewModel

当设置 ViewModelLocator.AutoWireViewModel = true 时,ViewModelLocationProvider 类会通过调用 AutoWireViewModelChanged 方法来解析 ViewModel 实例。解析规则如下:

  1. 先解析用户通过 ViewModelLocationProvider.Register 方法注册的 ViewModel
  2. 如果 1 失败,则通过基本约定规则进行解析ViewModel
    • View 和 ViewModel 位于同一个程序集中
    • View 在 .Views 子命名空间中,ViewModel 在 .ViewModels 子命名空间中
    • ViewModel名称与 View 对应并以 “ViewModel” 结尾

Prism_05_ViewModelLocator_第1张图片

自定义命名解析规则

如果不想遵循 ViewModelLocator 默认的命名约定,可以自定义约定,ViewModelLocator 会根据你自己定义的约定将 View 关联到 ViewModel.

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
    {
        var viewName = viewType.FullName.Replace(".ViewModels.", ".CustomNamespace.");
        var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
        var viewModelName = $"{viewName}ViewModel, {viewAssemblyName}";
        return Type.GetType(viewModelName);
    });
}

明确指定ViewModel

有时候,不需要 ViewModelLocator 尝试根据自定义命名约定来解析 ViewModel,可以直接手动指定将 ViewModel 指定给对应的 View.

// Type / Type
ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), typeof(CustomViewModel));
// Type / Factory
ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), () => Container.Resolve<CustomViewModel>());
// 通用工厂
ViewModelLocationProvider.Register<MainWindow>(() => Container.Resolve<CustomViewModel>());
// 通用类型
ViewModelLocationProvider.Register<MainWindow, CustomViewModel>();

这种通过 ViewModelLocationProvider.Register 手动指定 ViewModel 的方式更快,效率更高。

自定义ViewModel解析方式

默认情况,ViewModelLocator 使用选择的DI容器来解析 ViewModel。如果需要自定义解析方式或者更改解析器,可以使用 ViewModelLocationProvider.SetDefaultViewModelFactory方法。

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    ViewModelLocationProvider.SetDefaultViewModelFactory((view, viewModelType) =>
    {
        switch (view)
        {
            case Window window:
                //your logic
                break;
            case UserControl userControl:
                //your logic
                break;
        }

        return MyAwesomeNewContainer.Resolve(someNewType);
    });
}

我的公众号 HelloPragram

Prism_05_ViewModelLocator_第2张图片

你可能感兴趣的:(Prism,wpf,mvvm,c#)