WPF——Prism介绍
一.Prism介绍

二.程序启动
1.方式1 8.0版本之前的方案
首先创建,Views和ViewModels文件夹,然后分别创建一个ViewModel类,以及一个View界面。
public class InfoViewModel { public InfoViewModel() { myVar = 333; } private int myVar; public int MyProperty { get { return myVar; } set { myVar = value; } } } public partial class InfoView : Window { public InfoView() { InitializeComponent(); this.DataContext = new InfoViewModel(); } } <TextBlock Text="{Binding MyProperty}" FontSize="25"></TextBlock>
然后,编写一个BootStraper类,继承自Prism.Unity下面的PrismBootstrapper类。复写对应的方法。
public class BootStraper : PrismBootstrapper { protected override DependencyObject CreateShell() { return Container.Resolve<InfoView>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { } }
最后,在App.xaml.cs中,复写onstartup方法。
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var bs = new BootStraper(); bs.Run(); } }
启动程序就可以实现数据的绑定。
方式二,8.0版本提供的方式
需要修改App.xaml和App.xaml.cs里面的代码。
public partial class App : PrismApplication { //protected override void OnStartup(StartupEventArgs e) //{ // base.OnStartup(e); // var bs = new BootStraper(); // bs.Run(); //} protected override Window CreateShell() { return Container.Resolve<InfoView>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { } }
app.xaml.cs中的代码,需要继承自PrismApplication,复写其中的两个方法。
在app.xaml中也需要更改。
<prism:PrismApplication xmlns:prism="http://prismlibrary.com/" x:Class="Prism_01.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Prism_01" > <Application.Resources> </Application.Resources> </prism:PrismApplication>
自动注入数据,可以直接将datacontext数据删除掉。这种是根据命名规则来进行自动注入的。*View与*ViewModel进行自动匹配,自动绑定。条件是文件夹名称为Views和ViewModels。
三.数据绑定
1.自定义对应规则
也可以自定文件夹和文件的命名规则,实现自动注入数据。在App.xaml.cs下面建立对应关系。,输入的是view的类型,返回的是viewmodel的类型。
protected override void ConfigureViewModelLocator() { base.ConfigureViewModelLocator(); //设置统一的对应规则 ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType)=> { //将view文件名替换为viewmodel文件名 var modelName= viewType.FullName.Replace("ANDONGLU.", "").Replace("View","ViewModel").Replace("AN",""); //将view的dll名替换为viewmodel的dll名称。 var moduleName = viewType.Assembly.FullName; var t = $"{modelName },{moduleName}"; return Type.GetType(t); }); }
2.也可以建立一对一的对应关系
//一对一注册,string->type ViewModelLocationProvider.Register(typeof(ANInfoView).ToString(), typeof(InfoViewModel)); //type->type ViewModelLocationProvider.Register<ANInfoView, InfoViewModel>(); //string=>func ViewModelLocationProvider.Register(typeof(ANInfoView).ToString(), () => { return Container.Resolve<InfoViewModel>(); });
3.在datacontext中引入对象
<Window.DataContext> <prism:ContainerProvider Type="{x:Type vm:InfoViewModel}"></prism:ContainerProvider> </Window.DataContext>
四.数据双向绑定
public class InfoViewModel:BindableBase { public InfoViewModel() { myVar = 333; } private int myVar; public int MyProperty { get { return myVar; } set { myVar = value; //this.RaisePropertyChanged(); //设置属性值 //this.SetProperty<int>(ref myVar,value); //设置属性值的同时,提供回调函数,当值变化值可以调用 //this.SetProperty<int>(ref myVar,value,()=> { //}); } } }
ViewModel类需要继承自BindableBase类型,然后需要在属性的set里面设置值变化的通知。
Prism提供了多种通知方式。
五.数据验证
数据的验证可以在特性里面进行验证。在Prism.Unity里面是通过属性之中编写验证规则进行验证。验证结果需要放置到ErrorContainer里面。通过继承INotifyDataErrorInfo,处理Error信息。所有的验证代码都是在ViewModel里面实现的。
public class InfoViewModel:BindableBase, INotifyDataErrorInfo { public InfoViewModel() { myVar = 333; } private int myVar; public int MyProperty { get { return myVar; } set { //myVar = value; //this.RaisePropertyChanged(); //this.SetProperty<int>(ref myVar,value); this.SetProperty<int>(ref myVar, value, () => { }); if (value == 1231 || value == 12322) { ErrorContainer.SetErrors("MyProperty", new string[] { "输入值有误!" }); } else { ErrorContainer.ClearErrors("MyProperty"); } } } private ErrorsContainer<string> errorContainer; public ErrorsContainer<string> ErrorContainer { get { if (errorContainer == null) { errorContainer = new ErrorsContainer<string>(propName=> { ErrorsChanged?.Invoke(this,new DataErrorsChangedEventArgs(propName)); }); } return errorContainer; } set { errorContainer = value; } } public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public bool HasErrors => ErrorContainer==null?false:ErrorContainer.HasErrors; public IEnumerable GetErrors(string propertyName) =>ErrorContainer==null?null:ErrorContainer.GetErrors(propertyName); }
界面程序,需要在界面上添加一个Error提示,需要建立一个模板样式。
<Window x:Class="Prism_01.ANDONGLU.Views.ANInfoView" 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:Prism_01.ANDONGLU.Views" xmlns:vm="clr-namespace:Prism_01.ViewModels" xmlns:prism="http://prismlibrary.com/" mc:Ignorable="d" Title="AN" Height="450" Width="800"> <Window.DataContext> <prism:ContainerProvider Type="{x:Type vm:InfoViewModel}"></prism:ContainerProvider> </Window.DataContext> <Window.Resources> <ControlTemplate TargetType="{x:Type TextBox}" x:Key="ct"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True" CornerRadius="5"> <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" VerticalContentAlignment="Center" Margin="3,5" BorderThickness="0"/> </Border> <TextBlock Grid.Row="1" Text="{Binding (Validation.Errors)[0].ErrorContent,RelativeSource={RelativeSource AncestorType=TextBox,Mode=FindAncestor}}" Foreground="Red" Margin="10,5" Name="txtError"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="Visibility" Value="Visible" TargetName="txtError"/> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Window.Resources> <Grid> <StackPanel> <TextBlock Text="{Binding MyProperty}" FontSize="30"></TextBlock> <TextBox Text="{Binding MyProperty,UpdateSourceTrigger=PropertyChanged}" FontSize="30" Template="{StaticResource ct}"></TextBox> </StackPanel> </Grid> </Window>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步