8-10 ViewModelLocator Prism官网案例学习

声明

原文出处如下:

作者:RyzenAdorer 内容简介:Prism医疗案例

作者:可是我爱你啊 内容简介:Prism官方案例的学习分享

Prism官网开发文档

容器相关知识的学习

Microsoft官方文档

这是一篇记录作者学习Prism的随笔,该随笔的内容是作者通过5个资源学习汇总而成,主要是为了方便自己以后拾遗温习所用,如果文中内容看不懂,推荐直接阅读相关原文。

09-10 ViewModelLocator

使用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 (请参阅Custom ViewModel Registrations)。如果无法使用此方法解析ViewModel,则ViewModelLocationProvider退回到基于约定的方法来解析正确的ViewModel类型。

该约定假定:

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

更改ViewModelLocator命名约定

官方案例

如果您的应用程序不遵循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);
    });
}

博客案例

约定就是要来被打破的,有人可能觉得后缀加一个ViewModel实在是LowB,我想改变他,可以不可以?当然阔以啦。

prism为我们提供了一个可重写的ConfigureViewModelLocator的方法来配置ViewModel的定位器,如果你想修改默认的约定为View的名字后面+VM,你可以在app.xaml.cs这样写:

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

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

手动注册特定视图的ViewModel

官方介绍

在某些情况下,您的应用遵循ViewModelLocator默认的命名约定,但是您有许多不遵循约定的ViewModel。无需尝试自定义命名约定逻辑以有条件地满足您的所有命名要求,您可以ViewModelLocator使用ViewModelLocationProvider.Register方法直接使用来注册ViewModel到特定视图的映射。

以下示例说明了在称为的视图MainWindow和名为的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>();

注意

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

重要

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

博客案例

这世界上不乏个性鲜明的人,你们那些约定和打破的约定还不都是一路货色。我就要不一样的,我想跟谁绑在一起就跟谁绑在一起。好,你跟谁好是你的自由,Prism不能限制你,不然你会投诉它不民主。😂

如果你想指定你绑定的ViewModel对象又不想遵循一定的规则,你同样可以在ConfigureViewModelLocator方法中注册绑定,像下面这样:

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

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

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

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

            // generic type
            ViewModelLocationProvider.Register<MainWindow, CustomViewModel>();
        }

当然了,在xaml中的

prism:ViewModelLocator.AutoWireViewModel="True"

依旧是必不可少的。

posted @ 2020-08-10 01:46  AJun816  阅读(303)  评论(0编辑  收藏  举报