介绍
Prism提供了一组设计模式的实现,有助于编写结构良好的且可维护的XAML应用程序, 包括MVVM、依赖注入、命令、事件聚合器等。
核心:MVVM实现
支持平台:Prism.WPF、Prism.Forms、Prism.Uno
内置IOC:Autofac、DryIoc、Mef Ninject、StructureMap、Unity。最新8.0版本只保留了DryIoc和Unity。
官网:https://prismlibrary.com/
源码地址:https://github.com/PrismLibrary/Prism
针对WPF的Prism框架
Prism.Core:实现MVVM的核心功能,属于一个与平台无关的项目【Prism.dll】
Prism.Wpf:包含了DialogService、Region、Module、Navigation,其他的一些WPF的功能【Prism.Wpf.dll】
Prism.Unity:Ioc容器,比DryIoc使用市场更大一些【Prism.Unity.Wpf.dll】
Prism框架初始化
1、8.0以前版本—PrismBootstrapper
public class Bootstrapper : PrismBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<FirstWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
}
public partial class App
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bs = new Bootstrapper();
bs.Run();
}
}
2、8.0版本—PrismApplication
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<FirstWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//Ioc本质为对象集合,存相关的Type,取根据Type进行反射
}
}
View和ViewModel关联
1、自动关联
设置属性:prism:ViewModelLocator.AutoWireViewModel="True“
(1)必须是Views和ViewModels目录
(2)ViewModel必须以View的名称+”ViewModel”进行命名
2、自定义文件名关联规则
public partial class App : PrismApplication
{
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
///自定义ViewModel文件后缀,自动匹配
ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
{
//DemoViews.FirstWindow => DemoViewModels.FirstWindowVM
var viewName = viewType.FullName.Replace("DemoViews", "DemoViewModels");
var viewAssemblyName = viewType.Assembly.FullName;
var viewModelName = $"{viewName}VM,{viewAssemblyName}";
return Type.GetType(viewModelName);
});
}
}
3、直接代码一对一关联
public partial class App : PrismApplication
{
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
/// 一对一注册
ViewModelLocationProvider.Register(typeof(FirstWindow).ToString(), typeof(FirstWindowVM));
ViewModelLocationProvider.Register(typeof(FirstWindow).ToString(),
() => Container.Resolve<FirstWindowVM>()
);
ViewModelLocationProvider.Register<FirstWindow, FirstWindowVM>();
}
}
4、Xaml中设置DataContext
<Window.DataContext>
<prism:ContainerProvider Type="{x:Type vm:FirstWindowVM}"/>
</Window.DataContext>
Prism框架对象BindableBase
1、RaisePropertyChanged
private string myVar;
public string MyProperty
{
get { return myVar; }
set
{
myVar = value;
this.RaisePropertyChanged();
}
}
private string myVar;
public string MyProperty
{
get { return myVar; }
set
{
myVar = value;
// 通知其他属性
this.RaisePropertyChanged("其他属性名称");
}
}
2、SetProperty
private string myVar;
public string MyProperty
{
get { return myVar; }
set
{
//this.SetProperty(ref myVar, value);
this.SetProperty(ref myVar, value, "MyProperty");
}
}
private string myVar;
public string MyProperty
{
get { return myVar; }
set
{
this.SetProperty<string>(ref myVar, value,
() =>
{
//值改变的时候会触发,不改变不触发,onChanged
});
}
}
ErrorsContainer对象使用
Prism中提供的做数据验证时的一种方式,更推荐采用属性值上加特性来实现(更方便)。
//处理数据、值验证(ErrorsContainer)
public class FirstWindowVM : BindableBase, INotifyDataErrorInfo
{
private string myVar;
public string MyProperty
{
get { return myVar; }
set
{
this.SetProperty<string>(ref myVar, value,
() =>
{
// onChanged
});
// 基于ErrorsContainer的数据校验方式
if (value == "1231")
{
// 异常消息
ErrorsContainer.SetErrors("MyProperty", new string[] { "输入值无效1231231" });
}
else
{
ErrorsContainer.ClearErrors("MyProperty");
}
}
}
private ErrorsContainer<string> errorsContainer;
public ErrorsContainer<string> ErrorsContainer
{
get
{
if (errorsContainer == null)
errorsContainer = new ErrorsContainer<string>((propName) =>
{
//异常信息的处理
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propName));
});
return errorsContainer;
}
set { errorsContainer = value; }
}
/// <summary>
/// INotifyDataErrorInfo 接口方法
/// </summary>
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public bool HasErrors => ErrorsContainer.HasErrors;
public IEnumerable GetErrors(string propertyName) => ErrorsContainer.GetErrors(propertyName);
}