|
Prism的ViewModelLoctor对象个性化匹配、IOC、事件聚合器
<hr>更改命名约定
设计思路:
利用视图的类型全名称,将其中Views替换成ViewModels
检查类型是不是以View结尾
最终返回一个ViewModel的类型
新建文件夹/窗口【ViewTest/MainWindow.xaml】,代码如下:
<Window x:Class="WpfApp6.ViewTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp6.ViewTest" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="true" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <StackPanel> <TextBlock Text="您好"></TextBlock> <TextBlock Text="{Binding Value}"></TextBlock> </StackPanel> </Grid></Window> 新建文件夹/类【ViewModelTest/MainViewModel】,代码如下:using Prism.Mvvm;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace WpfApp6.ViewModelTest{ public class MainViewModel:BindableBase { private string _value = "Hellow Word"; public string Value { get { return _value; } set { SetProperty(ref _value, value); } } }}
App.xaml.cs 代码新增重写方法:【ConfigureViewModelLocator】 来配置个性化规则
using Prism.Ioc;using Prism.Mvvm;using Prism.Unity;using System;using System.Collections.Generic;using System.Configuration;using System.Data;using System.Linq;using System.Threading.Tasks;using System.Windows;namespace WpfApp6{ /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<ViewTest.MainWindow>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { } /// <summary> /// 配置ViewModelLocator的匹配规则 /// </summary> protected override void ConfigureViewModelLocator() { ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((t) => { //参数 t:需要匹配的视图 //返回需要匹配的ViewModel的类型 var viewName = t.FullName; var vmName = viewName.Replace(".ViewTest.", ".ViewModelTest."); if (vmName.EndsWith("Window")) vmName = vmName.Substring(0, vmName.Length - 6); if (vmName.EndsWith("View")) vmName += "Model"; else vmName += "ViewModel"; return Type.GetType(vmName); }); } }}
独立注册--4种方式
场景:
可能不在一个程序集
对象不在指定的目录
名称不匹配
解决方案为:独立注册,有四种方式
临时注册某一个关系对象
新建文件夹:【ViewTest/DemoWin.xaml】,实例代码如下:
<Window x:Class="WpfApp6.ViewTest.DemoWin" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" xmlns:local="clr-namespace:WpfApp6.ViewTest" mc:Ignorable="d" Title="DemoWin" Height="450" Width="800"> <Grid> <TextBlock Text="{Binding Value}"></TextBlock> </Grid></Window>
新建文件夹:【ViewModelTest/DemoViewModel.cs】,代码如下:
using Prism.Ioc;using Prism.Mvvm;using Prism.Unity;using System;using System.Collections.Generic;using System.Configuration;using System.Data;using System.Linq;using System.Threading.Tasks;using System.Windows;namespace WpfApp6{ /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<ViewTest.DemoWin>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { } /// <summary> /// 配置ViewModelLocator的匹配规则 /// </summary> protected override void ConfigureViewModelLocator() { //临时注册某一个关系对象 //1 类型对接类型 ViewModelLocationProvider.Register(typeof(ViewTest.DemoWin).ToString(),typeof(ViewModelTest.DemoViewModel)); } }}
类型 对接 工厂
protected override void ConfigureViewModelLocator() { //2 类型 对接 工厂 ViewModelLocationProvider.Register(typeof(ViewTest.DemoWin).ToString(),()=> { return Container.Resolve<ViewModelTest.DemoViewModel>(); }); }
通用工厂
protected override void ConfigureViewModelLocator() { //3 通用工厂 ViewModelLocationProvider.Register<ViewTest.DemoWin>(() => { return Container.Resolve<ViewModelTest.DemoViewModel>(); }); }
泛型类型
/// <summary> /// 配置ViewModelLocator的匹配规则 /// </summary> protected override void ConfigureViewModelLocator() { //4 泛型类型 ViewModelLocationProvider.Register<ViewTest.DemoWin,ViewModelTest.DemoViewModel>(); }
- IOC思想的应用与业务逻辑
Prism.Unity框架中自带了类对象注册的方法,在App.xaml.cs中的 RegisterTypes 方法,实例代码如下:
/// <summary> /// IOC容器对象的注册 /// </summary> /// <param name="containerRegistry"></param> protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.Register<IDataAccess, DataAccess>(); }
新建接口类与实现类,代码如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace WpfApp6.DAL{ public class DataAccess : IDataAccess { public string GetData() { return "世界和平!"; } }}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace WpfApp6.DAL{ public interface IDataAccess { string GetData(); }}
DemoViewModel代码如下:
using Prism.Mvvm;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using WpfApp6.DAL;namespace WpfApp6.ViewModelTest{ public class DemoViewModel : BindableBase { private string _value="世界和平!"; public string Value { get { return _value; } set { SetProperty(ref _value, value); } } // 构造函数注入 // public DemoViewModel(IDataAccess _data) // { // this.Value = _data.GetData(); // } //属性注入 [Dependency] private IDataAccess _data{get;set;} }}事件聚合器 【发布 订阅】
条件:
1、注入一个IEvevtAggragator
2、新建一个事件类并处理消息
代码实现如下
MainWindowViewModel类
using Prism.Commands;using Prism.Events;using Prism.Mvvm;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Input;using WpfApp7.Dal;using WpfApp7.Events;namespace WpfApp7.ViewModels{ public class MainWindowViewModel : BindableBase { private string _value = "世界和平!"; private readonly IEventAggregator eventAgs; public string Value { get { return _value; } set { SetProperty(ref _value, value); } } public MainWindowViewModel(IDataAccess da, IEventAggregator _eventAgs) { //订阅一个事件 eventAgs = _eventAgs; eventAgs.GetEvent<MessageEvent>().Subscribe((o) => { this.Value = o.ToString(); }); } /// <summary> /// 生产者 发布事件 /// </summary> public ICommand Btn_Send { get => new DelegateCommand<object>((p) => { eventAgs.GetEvent<MessageEvent>().Publish(p); }); } }}//备注: //Subscribe 参数 //第一个参数为:订阅者的执行Action //第二个参数为:ThreadOption 订阅者使用哪个线程来处理事件。 //是个枚举 //.PublisherThread 发布者的执行线程 默认 //.BackgroundThread 不管在哪个线程发布 这里的Action都在后台线程处理 //.UIThread 不管在哪个线程发布 这里的Action都在UI线程处理 //第三个参数 是个bool类型 是个开关 默认为 false //第四个参数 Predicate<TPayload> filter 过滤器
新建事件类:Events/MessageEvent 并继承 PubSubEvent<object> object是为传递的参数
using Prism.Events;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace WpfApp7.Events{ /// <summary> /// 定义一个事件类 /// </summary> public class MessageEvent:PubSubEvent<object> { }}
MainWindow.xaml 代码如下:
<Window x:Class="WpfApp7.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp7.Views" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <StackPanel> <Button Content="生产者" Command="{Binding Btn_Send}" CommandParameter="123"></Button> <TextBlock Text="{Binding Value}" ></TextBlock> </StackPanel> </Grid></Window>
|
|