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. 输入URL按下enter键后发生的事

    输入URL按下enter键后浏览器和服务器各自发生的事. 浏览器 1.用户在浏览器中输入URL地址 2.浏览器解析用户输入的URL地址=>域名+端口 3.浏览器检查本地缓存中是否存在这个域名=& ...

  2. 三伏天里小试牛刀andriod 开发 #华为云·寻找黑马程序员#

    2019年07月,北京,三伏天,好热啊.越热自己还越懒得动换(肉身给的信号),但是做为产品经理/交互设计师的,总想着思考些什么(灵魂上给的信号),或者是学习些什么,更有利于将来的职业发展吧,哈哈哈.工 ...

  3. 将Android手机打造成你的Python开发者桌面#华为云·寻找黑马程序员#

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...

  4. 如何把图片变得炫酷多彩,Python教你这样实现!

    有趣的图片 如何能让图片变得好玩?首先需要让它动起来!可如果是多张图片,我们还可以将其拼接起来组成gif动图,可一张图怎么玩?记得之前写过一个小练习,把一张图片拆分成九宫格的分片图.那么,能否由此下手 ...

  5. NRF52810和NRF52832的区别

    NRF52832和NRF52810都是蓝牙5.0的芯片 均是出至NORDIC. 主要区别是 1.NRF52810的Flash是192KB/ RAM是24KB    NRF52832的Flash是512 ...

  6. 使用Carthage集成Alamofire

    Carthage相较于Cocoapods有着使用灵活,对目标工程改动小的优势,使得它越来越受欢迎.今天就对我使用Carthage集成FBSDK做一个记录. 1.首先https://github.com ...

  7. iOS-使用Xcode自带单元测试UnitTest

    ![Uploading QQ20160129-3_262826.png . . .]####什么是单元测试?一听到单元测试这个词感觉很高端,其实单元测试就是为你的方法多专门写一个测试函数.以保证你的方 ...

  8. Creating your first iOS Framework

    转自:https://robots.thoughtbot.com/creating-your-first-ios-framework If you’ve ever tried to create yo ...

  9. dubbo 发布 RPC 服务

    Dubbo 发布 RPC 服务 建立服务提供者项目 pom.xml <?xml version="1.0" encoding="UTF-8"?> & ...

  10. 洛谷 题解 P5015 【标题统计】 NOIP2018 普及组 T1

    没有人用 scanf("%c", &ch) != EOF 吗? scanf 和 EOF 会伤心的. 思路:逐个读入字符,遇到EOF中止,对于每个读入的字符进行判断. 附上考 ...