WPF入门到跪下 第十一章 Prism(四)View与ViewModel的自动关联

View与ViewModel的自动关联

一、ViewModelLocator

在学习MvvmLight框架时,也使用了ViewModelLocator类。但在MvvmLight框架中,ViewModelLocator只是一个自定义类,与框架无关,目的就是初始化IoC容器。而在Prism框架中则不同,Prism框架内置了ViewModelLocator类,并且可以帮助我们进行ViewViewModel层之间的绑定。

1、使用示例

先查看一下整个使用过程,再进行解析。

程序集中,创建Views文件夹、ViewModels文件夹,将MainWindow.xaml放入Views文件夹中,并再ViewModels文件夹中创建MainWindowViewModel类

注意,在移动MainWindow.xaml时,切记要修改命名空间(xaml文件中的x:Class属性以及后台代码中的命名空间)

public class MainWindowViewModel:BindableBase
{
    private int value;

    public int Value
    {
        get { return value; }
        set
        {
            SetProperty(ref this.value, value);
        }
    }
}

在这里插入图片描述

在MainWindow.xaml中进行Prism命名空间的引入以及ViewModelLocator.AutoWireViewModel属性的设置

需要注意,AutoWireViewModel默认就是为True,表示自动关联ViewModel,因此这个命名空间引入以及设置属性的步骤是可以省略的。

<Window ......
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
				......>
    <Grid>
        <TextBlock Text="{Binding Value}"/>
    </Grid>
</Window>

2、关联规则

通过ViewModelLocator进行View与ViewModel层的自动关联,有以下几点规则:

  • ViewModel与视图类型位于同一个程序集中
  • ViewModel位于.ViewModels子命名空间中,测试后发现其实.ViewModel子命名空间中也可以。
  • View位于.Views子命名空间中,测试后发现其实.View子命名空间中也可以。
  • ViewModel名称与视图名称对应,以ViewModel结尾。这里有一点需要注意的,如果视图的名称本身就是以View结尾的,例如StudentView,那么ViewModel名称中只要一个View就可以了,也就是StudentViewModel。

二、个性化配置

1、关联规则配置

这里以PrismApplication启动方式为例,在Prism框架中,会自动将View与ViewModel进行关联,其关联规则如上文所述。

默认关联过程大致如下:

  • 规定视图层的类型必须放在.Views命名控件的子空间下,然后将命名空间中的Views替换成ViewModels,来获得对应的视图模型的所在命名空间,例如Schuyler.Views -> Schuyler.ViewModels
  • 获得视图层的类类型后,检查类类型的全名是不是以View结尾,如果是则在尾部添加Model,否则则添加ViewModel,以此来获得视图层类类型所对应的视图模型层的类类型。
  • 通过视图层类类型命名空间获取到视图模型层的类类型后,将该视图模型层的实例对象设置为对应视图层实例对象的DataContext

根据上述关联过程,想要修改默认的关联规则,只需要在启动类(App)中,重写PrismApplication类的ConfigureViewModelLocator方法,并在方法中通过ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver方法来进行关联过程的修改即可。

ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(Func<Type, Type> viewTypeToViewModelTypeResolver):设置默认的视图类型与视图模型类型的分析器。

  • viewTypeToViewModelTypeResolver:接收一个Type类型参数,并返回一个Type类型的Func委托。接收的Type为视图类的类类型,而从哪个命名空间获取这个类类型应该是根据启动时设置的主窗口的所在命名空间来定下的。返回的Type则是根据接收到的Type参数的命名空间转化后获得的对应视图模型的类类型。

具体实现代码如下:

前提是使用PrismApplication进行项目启动,实现方式可以翻看前文。

这里是将ViewTest作为存放View类型的文件夹、ViewModelTest则是用来存放ViewModel类型的文件夹。

public partial class App : PrismApplication
{
    protected override Window CreateShell()
    {
        return Container.Resolve<ViewTest.MainWindow>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        
    }

    protected override void ConfigureViewModelLocator()
    {
        base.ConfigureViewModelLocator();
        ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(ViewTypeToViewModelTypeResolver);
    }

    private Type ViewTypeToViewModelTypeResolver(Type viewType)
    {
        var viewName = viewType.FullName;
        //获得视图模型的命名空间
        var viewModelName = viewName.Replace(".ViewTest.", ".ViewModelTest.");
        //判断视图类是不是以Window结尾,是则去掉
        if (viewModelName.EndsWith("Window"))
        {
            viewModelName = viewModelName.Substring(0, viewModelName.Length - 6);
        }
        //判断是不是以View结尾
        if (viewModelName.EndsWith("View"))
        {
            viewModelName += "Model";
        }
        else
        {
            viewModelName += "ViewModel";
        }
        return Type.GetType(viewModelName);
    }

}

2、独立关联规则配置

上面所说得关联规则配置指的是整个项目内都必须遵守的,而有些时候只希望配置某对View与ViewModel的关联规则,比如View与ViewModel可能不再一个程序集、不在指定目录、类型名字不匹配等。

此时则需要重写PrismApplication类的ConfigureViewModelLocator方法,并在方法中通过调用ViewModelLocationProvider.Register方法来进行单独的配置,具体由如下四种配置方法:

public partial class App : PrismApplication
{
    protected override Window CreateShell()
    {
        //创建主窗口对象
        return Container.Resolve<ViewTest.MainWindow>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        //这里进行IOC容器管理类型的注册
    }

    protected override void ConfigureViewModelLocator()
    {
        base.ConfigureViewModelLocator();
        //方式1:通过 类型名称/类型
        //ViewModelLocationProvider.Register(typeof(ViewTest.MainWindow).ToString(), typeof(ViewModelTest.MainViewModel));
        //方式2:通过 类型/工厂
        //ViewModelLocationProvider.Register(typeof(ViewTest.MainWindow).ToString(), 
        //    ()=>Container.Resolve<ViewModelTest.MainViewModel>());
        //方式3:通过 泛型/工厂
        //ViewModelLocationProvider.Register<ViewTest.MainWindow>(() => Container.Resolve<ViewModelTest.MainViewModel>());
        //方式4:通过 泛型
        ViewModelLocationProvider.Register<ViewTest.MainWindow, ViewModelTest.MainViewModel>();
    }
}
  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
WPF(Windows Presentation Foundation)是一个用于创建 Windows 应用程序的框架,而 Prism 是一个基于 WPF 的框架,它提供了一组设计模式和工具,用于帮助开发人员创建可扩展、可重用和易于维护的应用程序。 在 Prism 中,ViewModel 是一个重要的组件,它的作用是将 View(即用户界面)与 Model(即数据和业务逻辑)解耦,使得两者可以独立进行开发和测试。 在 Prism 中,ViewModel 通常是一个简单的类,它实现了 INotifyPropertyChanged 接口,用于实现数据绑定ViewModel 还包含了一些命令(Command),用于处理用户交互事件,比如按钮点击、菜单选择等。ViewModel 还可以使用服务(Service)来访问 Model,以获取或操作数据。 下面是一个简单的 ViewModel 的示例: ```csharp public class MainViewModel : BindableBase { private readonly IMyService _myService; private string _name; public string Name { get { return _name; } set { SetProperty(ref _name, value); } } private ICommand _helloCommand; public ICommand HelloCommand { get { if (_helloCommand == null) { _helloCommand = new DelegateCommand(ExecuteHelloCommand); } return _helloCommand; } } public MainViewModel(IMyService myService) { _myService = myService; } private void ExecuteHelloCommand() { string message = _myService.GetMessage(Name); MessageBox.Show(message); } } ``` 在上面的代码中,MainViewModel 包含了一个字符串属性 Name 和一个 ICommand 属性 HelloCommand。Name 属性用于将用户界面中的文本框绑定ViewModel 中,而 HelloCommand 则表示用户点击“Hello”按钮时要执行的命令。HelloCommand 的实现是通过调用一个服务(IMyService)来获取一条消息,然后通过 MessageBox 显示出来。 需要注意的是,MainViewModel 的构造函数中注入了一个 IMyService 接口,这个接口封装了对数据和业务逻辑的访问,使得 ViewModel 可以与具体的实现解耦。这种依赖注入的方式可以使得应用程序的组件更加松散耦合,更加易于维护和测试。 总之,ViewModelWPF Prism 中非常重要的一个组件,它用于实现视图与模型之间的解耦和交互。开发人员可以使用 ViewModel 实现数据绑定、命令处理、服务访问等功能,从而创建可扩展、可重用和易于维护的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SchuylerEX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值