ViewModelLocator

ViewModelLocator用于绑定视图的DataContext,以使用标准命名约定的一个ViewModel的实例。

Prism ViewModelLocator有一个AutoWireViewModel附加属性,当设置为true调用类中的AutoWireViewModelChanged方法ViewModelLocationProvider来解析视图的ViewModel时,然后将视图的数据上下文设置为该ViewModel的实例。

AutoWireViewModel附加属性添加到每个视图:

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

要查找ViewModel,ViewModelLocationProvider首先尝试从ViewModelLocationProvider.Register方法注册的任何映射中解析ViewModel (请参阅自定义ViewModel注册)。如果使用此方法无法解析ViewModel,则会ViewModelLocationProvider回退到基于约定的方法来解析正确的ViewModel类型。

该惯例假定:

  • ViewModel与视图类型位于同一个程序集中
  • ViewModel位于.ViewModels子命名空间中
  • 视图位于.Views子命名空间中
  • ViewModel名称与视图名称对应,以“ViewModel”结尾。

注意

ViewModelLocationProvider可以在发现Prism.Mvvm命名空间中的Prism.Core NuGet包。本ViewModelLocator可以在发现Prism.Mvvm命名空间中的Prism.WPF NuGet包。

注意

ViewModelLocator是必需的,并且在使用Xamarin.Forms进行开发时会自动应用于每个View,因为它负责向INavigationServiceViewModel 提供正确的实例。在开发Xamarin.Forms应用程序时,ViewModelLocator只能选择退出。

视频教程1

[Using the ViewModelLocator视频教程](Prism.assets/Prism - Using the ViewModelLocator.mp4)

更改命名约定

如果您的应用程序不遵循ViewModelLocator默认命名约定,则可以更改约定以满足应用程序的要求。本ViewModelLocationProvider类提供了一个称为静态方法SetDefaultViewTypeToViewModelTypeResolver,可以用来提供自己的约定关联视图查看模型。

要更改ViewModelLocator命名约定,请覆盖类中的ConfigureViewModelLocator方法App.xaml.cs。然后在ViewModelLocationProvider.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);
});
}

视频教程2

[Changing the ViewModelLocator Naming Convention视频教程](Prism.assets/Prism - Changing the ViewModelLocator Naming Convention.mp4)

自定义ViewModel注册

可能存在您的应用程序遵循ViewModelLocator默认命名约定的情况,但您有许多不符合约定的ViewModel。您可以ViewModelLocator使用该ViewModelLocationProvider.Register方法直接将ViewModel的映射注册到特定视图,而不是尝试自定义命名约定逻辑以有条件地满足所有命名要求。

以下示例显示了在名为MainWindow的ViewModel和ViewModel 之间创建映射的各种方法CustomViewModel

类型/类型

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>();
注意

直接注册ViewModel ViewModelLocator比依赖默认命名约定更快。这是因为命名约定需要使用反射,而自定义映射直接提供类型ViewModelLocator

重要

viewTypeName参数必须是视图的Type(Type.ToString())的完全限定名称。否则映射将失败。

视频教程3

[ViewModelLocator Custom Registrations视频教程](Prism.assets/Prism - ViewModelLocator Custom Registrations.mp4)

控制ViewModel的解析方式

默认情况下,ViewModelLocator将使用您选择的DI容器来创建Prism应用程序以解析ViewModels。但是,如果您需要自定义ViewModel的解析方式或完全更改解析器,则可以使用该ViewModelLocationProvider.SetDefaultViewModelFactory方法实现此目的。

此示例显示如何更改用于解析ViewModel实例的容器。

protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator(); ViewModelLocationProvider.SetDefaultViewModelFactory(viewModelType) =>
{
return MyAwesomeNewContainer.Resolve(viewModelType);
});
}

这是一个示例,说明如何检查为其创建ViewModel的视图类型,以及执行逻辑来控制ViewModel的创建方式。

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);
});
}

Prism_ViewModelLocator(5)的更多相关文章

随机推荐

  1. 华为云OCR文字识别 免费在线体验!

    嘿,华为云OCR文字识别了解一下,免费在线体验! 物流行业快速提取运单信息.医疗/保险行业单据快速录入.政务办事人证检验,你知道这些都是如何实现的么? 答案就是:OCR文字识别! 作为AI时代效率倍增 ...

  2. SpringBoot中JdbcTemplate

    步骤如下: 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...

  3. CodeChef FAVNUM FavouriteNumbers(AC自动机+数位dp+二分答案)

    All submissions for this problem are available. Chef likes numbers and number theory, we all know th ...

  4. io流函数略解(java_input流)[二]

    背景 在写这篇随笔之前,已经写了io流函数略解(java_File)(一),主要是总结了File的一些操作,以及一些源码介绍. 在Io实际应用中,实际上运用在如果会操作File,实际上很难写出一点能实 ...

  5. 基于LAMP php7.1搭建owncloud云盘与ceph对象存储S3借口整合案例

    ownCloud简介 是一个来自 KDE 社区开发的免费软件,提供私人的 Web 服务.当前主要功能包括文件管理(内建文件分享).音乐.日历.联系人等等,可在PC和服务器上运行. 简单来说就是一个基于 ...

  6. unity3d 动态添加地面贴图 草地

    TerrainData.splatPrototypes = ]{ new SplatPrototype() { texture=Caodi, //Texture2D的贴图 normalMap=null ...

  7. linux-touch 、mkdir、rm、pwd、which、locate、whatis

    1.touch: 创建空文件,修改文件时间戳信息 atime(access time):最近访问文件内容时间 mtime(modify time):最近修改文件内容时间 ctime(change ti ...

  8. Seata 配置中心实现原理

    Seata 可以支持多个第三方配置中心,那么 Seata 是如何同时兼容那么多个配置中心的呢?下面我给大家详细介绍下 Seata 配置中心的实现原理. 配置中心属性加载 在 Seata 配置中心,有两 ...

  9. 机会来了!5G时代带来新闻传播行业的变革!

    5G时代到来!新闻传播行业大变革! 1.作为一名体育生进入的新闻传播学院,传统的新闻媒体能力已不再具有优势,意味着我有翻身的机会了! 从一开始进入大学,由于高中的知识储备不如其他人,尤其是英语能力方面 ...

  10. Koa中间件(middleware)级联原理

    前言 上次看到了koa-compose的代码,今天来说一下koa中间件的级联以及工作原理. 中间件工作原理 初始化koa实例后,我们会用use方法来加载中间件(middleware),会有一个数组来存 ...