Prism 开发之四 ViewModelLocator

1、概况     

  Prism具有附加属性,当设置为调用类中的方法来解析视图模型以进行查看,然后将视图的数据上下文设置为该视图模型的实例时。使用以下附加属性。设置选择退出和明确选择加入的价值。AutoWireViewModelFalseTrue

<Window x:Class="Demo.Views.MainWindow" ... xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="False">

要找到视图模型,如果无法使用此方法解决 ViewModel,则返回到基于惯例的方法来解决正确的视图模型类型。

containerRegistry.Register<Services.ICustomerStore, Services.DbCustomerStore>();

本公约假定:

  • 视图模组与视图类型处于相同的组件中
  • 视图模组位于儿童命名空间中.ViewModels
  • 视图位于儿童命名空间中.Views
  • 视图模型名称与视图名称相对应,并以"查看模型"结尾。

  可以在Prism中. 核心Nuget 包的命名空间中找到。可以在平台特定包(Prism.WPF,棱镜.形式)的命名空间中找到 NuGet 包。ViewModelLocationProviderPrism.MvvmViewModelLocatorPrism.Mvvm

2、更改命名公约

  如果您的申请未遵循默认命名惯例,您可以更改该公约以满足您的申请要求。该类提供了一种静态方法,可用于提供您自己的约定,以便关联视图以查看模型。SetDefaultViewTypeToViewModelTypeResolver 

要更改命名约定,要在类中覆盖该方法。然后在方法中提供您的自定义命名惯例逻辑。ViewModelLocatorConfigureViewModelLocatorApp.xaml.csViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver

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);
    });
}
3、自定义视图模型注册

  可能有以下情况表明,您的应用遵循默认命名惯例,但您有许多视图模组不符合该公约。您可以使用该方法直接注册 ViewModel 的映射,而不是尝试自定义命名会议逻辑以有条件地满足您的所有命名要求。

ViewModelLocatorViewModelLocatorViewModelLocationProvider.Register

  以下示例显示了在称为"查看"和"查看模型"之间创建映射的各种方法。MainWindowCustomViewModel

  类型 / 类型

ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), typeof(CustomViewModel));

  类型/ 工厂

ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), () => Container.Resolve<CustomViewModel>());

  通用工厂

ViewModelLocationProvider.Register<MainWindow>(() => Container.Resolve<CustomViewModel>());

  通用类型

ViewModelLocationProvider.Register<MainWindow, CustomViewModel>();
  注意

  直接在 ViewModels 上注册比依赖默认命名约定要快。这是因为命名公约需要使用反射,而自定义映射直接提供类型到 。ViewModelLocatorViewModelLocator

重要

  参数必须是视图类型()的完全合格名称。否则映射将失败。viewTypeNameType.ToString()

4、控制如何解决视图模型

  默认情况下,将使用您选择的 DI 容器创建您的棱镜应用程序来解析视图模组。但是,如果您需要自定义"查看模式"的解析方式或完全更改解析器,则可以通过使用该方法实现此目标。ViewModelLocatorViewModelLocationProvider.SetDefaultViewModelFactory

此示例显示了如何更改用于解决"查看模型"实例的容器。

protected override void ConfigureViewModelLocator() { 

base.ConfigureViewModelLocator();
ViewModelLocationProvider.SetDefaultViewModelFactory(viewModelType) => {
return MyAwesomeNewContainer.Resolve(viewModelType);
});
}
这是一个示例,说明您可以如何检查"查看模型"创建的视图类型,并执行逻辑来控制"视图模型"的创建方式。
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); });
}

原文地址:https://www.cnblogs.com/minhost/p/15158153.html