WPF入门到跪下 第十一章 Prism(一)数据处理

本文介绍了Prism框架,一个由微软维护的开源框架,特别关注MVVM模式、数据处理(如BindableBase和属性变化通知)、以及错误处理机制。详细讲解了如何通过Nuget安装相关库,以及在WPF中使用Prism的特性进行开发。
摘要由CSDN通过智能技术生成

官网:https://primslibrary.com
源码地址:https://guthub.com/PrismLibrary/prism
Prism是由微软发布、维护的开源框架,提供了一组设计模式的实现,有助于编写结构良好的且可维护的XAML应用程序,包括MVVM、依赖注入、命令、事件聚合器等。
关键程序集
Prism.Core:实现MVVM的核心功能,是一个与平台无关的项目,可以在多个开发平台中使用(Prism.dll)。

  • 如果只需要实现MVVM中的一些简单功能、例如属性变化通知、命令等,只需要在Nuget中安装Prism.Core库即可。在这里插入图片描述

Prism.Wpf:包含了DialogServiceRegionModuleNavigation和其他一些WPF功能,使得WPF开发更加方便快捷(Prism.Wpf.dll)。

  • 如果需要进一步使用WPF中的一些其他功能,可以在Nuget中安装Prism.Wpf库,由于Prism.Wpf依赖于Prism.Core因此,无需再安装Prism.Core

    在这里插入图片描述

Prism.Unity:包含Prism.Unity.Wpf.dllPrism.DryIoc.Wpf.dll

  • 如果需要使用IOC,则需要安装Prism.Unity,由于Prism.Unity依赖于Prism.Wpf,因此不需要再安装Prism.WpfPrism.Core

    在这里插入图片描述

数据处理

一、属性变化通知

Prism框架提供了BindableBase类,用于做数据处理(例如属性的变化通知等)。

五种属性变化通知方式

通过继承BindableBase类,可以更加便捷地在WPF中实现属性变化通知,具体有如下五种方式。
其中前三种没啥特殊的,第四种方式可以在属性变化时,通知其他属性的绑定控件;而第五种方式则可以在属性发生变化后调用指定的函数。

public class MainViewModel : BindableBase
{
    private string _value;

    public string Value
    {
        get { return _value; }
        set 
        {
            // 第一种方式
            SetProperty(ref _value, value);

            // 第二种方式
            //this.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Value"));

            // 第三种方式
            //this.RaisePropertyChanged();

            // 第四种方式:可以通知另一个属性
            //SetProperty(ref _value, value, "Var");

            // 第五种方式
            //SetProperty(ref _value, value, OnValueChanged);
        }
    }
	private void OnValueChanged()
    {
        //属性成功变化后的执行函数
    }
}

二、数据异常处理

Prism框架提供了ErrorsContainer<T>类型专门用于处理项目中出现地异常。其中泛型T为指定的异常消息类型。

1、INotifyDataErrorInfo接口

使用ErrorsContainer<T>需要实现INotifyDataErrorInfo接口。
实现INotifyDataErrorInfo接口主要需要实现其中的三个成员,分别如下:

event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged:事件属性成员,用于异常通知。

bool HasErrors:属性成员,用于判断是否存在异常。

  • 一般会通过ErrorsContainer对象的HasErrors属性来进行判断。

IEnumerable GetErrors(string propertyName):方法成员,用于获取相关属性名称的异常。

  • 一般会通过ErrorsContainer对象的GetErrors方法来获得对应属性的异常。
public class MainViewModel :INotifyDataErrorInfo
{
    //声明ErrorsContainer对象,这里没有定义,详细做法请看下文
    public ErrorsContainer<string> _errorsContainer;

    public bool HasErrors => _errorsContainer.HasErrors;

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
        return _errorsContainer.GetErrors(propertyName);
    }
		......
}

2、ErrorsContainer类

构造函数

ErrorsContainer<T>(Action<string> raiseErrorsChanged):创建ErrorsContainer对象。

  • raiseErrorsChanged:发生异常时的执行函数,函数中要去触发异常发生事件,也就是INotifyDataErrorInfo接口的ErrorsChanged事件成员。

常用成员

bool HasErrors:属性成员,用于判断当前是否存在异常。

IEnumerable<T> GetErrors(string propertyName):获取指定属性的异常集合。

  • propertyName:要获取异常的属性名称。

SetErrors(string propertyName, IEnumerable<T> newValidationResults):设置异常(也就是发生异常了)。

  • propertyName:触发异常的属性名称。
  • newValidationResults:异常集合,可以是string数组,也可以是其他类型数组。

3、具体实现过程

异常处理编写
实现INotifyDataErrorInfo接口

public class MainViewModel : INotifyDataErrorInfo
{
    public bool HasErrors => throw new NotImplementedException();

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
        throw new NotImplementedException();
    }
}

定义ErrorsContainer<T>对象属性,完善INotifyDataErrorInfo成员实现

public class MainViewModel : INotifyDataErrorInfo
{
		//定义异常属性
    private ErrorsContainer<string> _errorsContainer;
    public ErrorsContainer<string> ErrorsContainer
    {
        get 
        {
            if (_errorsContainer == null)
            {
                _errorsContainer = new ErrorsContainer<string>(OnErrorHappend);
            }
            return _errorsContainer; 
        }
    }
		
		//当异常发生时,触发异常发生事件
    private void OnErrorHappend(string obj)
    {
        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(obj));
    }

    public bool HasErrors => ErrorsContainer.HasErrors;

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
        return ErrorsContainer.GetErrors(propertyName);
    }
}

继承BindableBase类,定义属性并实现属性变化通知,在特定条件下发生异常

public class MainViewModel : BindableBase,INotifyDataErrorInfo
{
    ......//上文的内容

    private int _value;

    public int Value
    {
        get { return _value; }
        set 
        {
            if (value > 10)
            {
                ErrorsContainer.SetErrors("Value", new string[] { "数值不能大于10" });
            }
            SetProperty(ref _value, value); 
        }
    }
}

异常消息展示

在xaml中进行异常消息的使用

<Window ......>
    <Window.DataContext>
        <local:MainViewModel/>
    </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 Value}"/>
            <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}" Template="{StaticResource ct}"/>
        </StackPanel>
    </Grid>
</Window>
  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以回答这个问题。WPF Prism 是一个用于构建可扩展、模块化 WPF 应用程序的框架。下面是一个简单的 WPF Prism 示例: 1. 创建一个新的 WPF 应用程序项目。 2. 在项目中添加 Prism 库的引用。 3. 在 App.xaml.cs 文件中,添加以下代码: using Prism.Unity; using Microsoft.Practices.Unity; namespace WpfPrismExample { public partial class App : PrismApplication { protected override void RegisterTypes(IUnityContainer container) { // 注册服务 container.RegisterType<IMyService, MyService>(); } protected override void ConfigureModuleCatalog() { // 配置模块 ModuleCatalog.AddModule(new ModuleInfo() { ModuleName = "MyModule", ModuleType = typeof(MyModule), InitializationMode = InitializationMode.WhenAvailable }); } protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // 启动应用程序 var mainWindow = Container.Resolve<MainWindow>(); mainWindow.Show(); } } } 4. 创建一个名为 MyModule 的模块,并在其中添加一个名为 MyView 的视图和一个名为 MyViewModel 的视图模型。 5. 在 MainWindow.xaml 中,添加以下代码: <Window x:Class="WpfPrismExample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" Title="MainWindow" Height="350" Width="525"> <Grid> <prism:RegionManager.RegionName="MainRegion" /> </Grid> </Window> 6. 在 MainWindow.xaml.cs 中,添加以下代码: using Prism.Regions; namespace WpfPrismExample { public partial class MainWindow : Window { public MainWindow(IRegionManager regionManager) { InitializeComponent(); // 注册区域 regionManager.RegisterViewWithRegion("MainRegion", typeof(MyView)); } } } 这个例子演示了如何使用 WPF Prism 构建一个简单的模块化应用程序。当应用程序启动时,它会加载 MyModule 模块,并在 MainWindow 中显示 MyView 视图。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SchuylerEX

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

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

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

打赏作者

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

抵扣说明:

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

余额充值