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

官网: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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/334261.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

前言 在项目研发中&#xff0c;相信大家都遇到过给用户增加头像照片的需求。 随着手机版本的不断更新&#xff0c;android 8、android 9、android 10、android 12、android 13、鸿蒙系统等等&#xff1b;遇到这个功能需求&#xff0c;大家肯定会想&#xff0c;“这还不好写&…

一键AI智能改写,自动修改文章效率高

在当今信息爆炸的时代&#xff0c;写作成为了人们日常生活和工作中不可或缺的一部分。不论是学生写作业&#xff0c;还是职场人士起草报告&#xff0c;都需要投入大量的时间和精力来构思和修改文章。然而&#xff0c;随着科技的不断进步&#xff0c;一项新的技术正在改变着写作…

HTML111111111

在线编辑器 在线 HTML 空元素 没有内容的 HTML 元素被称为空元素。空元素是在开始标签中关闭的。 即使 在所有浏览器中都是有效的&#xff0c;但使用 其实是更长远的保障。 HTML 水平线 标签在 HTML 页面中创建水平线。 hr 元素可用于分隔内容。 HTML 折行 如果您希望…

免费的爬虫软件【2024最新】

在国际市场竞争日益激烈的背景下&#xff0c;国外网站的SEO排名直接关系到网站在搜索引擎中的曝光度和用户点击量。良好的SEO排名能够带来更多的有针对性的流量&#xff0c;提升网站的知名度和竞争力。 二、国外网站SEO排名的三种方法 关键词优化&#xff1a; 关键词优化是SEO…

Java基础面试题-2day

面向对象 创建一个对象用什么运算符&#xff0c;对象实体和对象引用有什么不同&#xff1f; 创建对象使用new String A new String(); A即为对象引用&#xff0c;通过new运算符&#xff0c;创建String()类型的对象实体。 对象引用的存储位置在栈内存 对象实体的存储位置在堆…

分布式事务Seata实战-AT模式(注册中心为Eureka)

大致记录Seata的AT模式下创建项目过程中需要注意的点和可能遇到的问题。 本项目是以官网的给的示例&#xff08;即下图&#xff09;进行创建的&#xff0c;以Eureka为注册中心。 官网&#xff1a;Seata AT 模式 | Apache Seata™ 官方代码示例&#xff1a; 快速启动 | Apac…

C++编写、生成、调用so库详解(一)

开发中经常会用到so库,大多是调用第三方的so库,偶尔也需要自己封装一个so库给别人调用,这边就记录一下开发so库的一个过程. 首先我们这边是在Android Studio中开发的,所以仅描述在Android环境下开发过程,当然也可以用其他工具开发. 目录 1.第一步新建项目,配置需要的工具 2…

MFTCoder 重磅升级 v0.3.0 发布,支持 Mixtral 等更多模型,支持收敛均衡,支持 FSDP

1. MFTCoder 简介 CodeFuse在2023年9月开源了一种多任务微调框架——MFTCoder&#xff0c;它可以实现在多个任务上同时并行地进行微调。通过结合多种损失函数&#xff0c;我们有效地解决了多任务学习中常见的任务间数据量不平衡、难易不一和收敛速度不一致等挑战。大量实验结果…

『Open3D』1.10 Tensor数据处理

open3d中实现了自身的数据类型,用于open3d中内部算法的数值计算,但基础使用上与numpy类似。 目录 1、tensor创建 2、tensor数据属性 3、 Tensor数据在CPU与GPU上的转换

An incompatible version [1.2.33] of the Apache Tomcat Native library is installed

ERROR&#xff1a;An incompatible version [1.2.33] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.34] 意为&#xff1a;安装了不兼容的Apache Tomcat原生库版本[1.2.33]&#xff0c;而Tomcat需要的版本[1.2.34] ERROR 14496 ---…

工业相机与镜头参数及选型

文章目录 1、相机成像系统模型1.1 视场1.2 成像简化模型 2、工业相机参数2.1 分辨率2.2 靶面尺寸2.3 像元尺寸2.4 帧率/行频2.5 像素深度2.6 动态范围2.7 信噪比2.8 曝光时间2.9 相机接口 3、工业镜头参数3.1 焦距3.2 光圈3.3 景深3.4 镜头分辨率3.5 工作距离&#xff08;Worki…

表的增删改查 进阶(二)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 3.新增 4.查询 聚合查询 聚合函数 GROUP BY子句 HA…

【GitHub项目推荐--一键换脸】【转载】

FaceSwap 是一种利用深度学习算法来换掉图片和视频中的人脸的工具。基于 Tensorflow、Keras 和 Python&#xff0c;Faceswap 可以在 Windows、macOS 和 Linux 上运行。 安装了这个应用&#xff0c;你就能在你电脑上通过可视化交互的方式构建自己的换脸模型了。 地址&#xff…

时序分解 | Matlab实现CEEMDAN+PE自适应噪声完备集合经验模态分解+排列熵计算

时序分解 | Matlab实现CEEMDANPE自适应噪声完备集合经验模态分解排列熵计算 目录 时序分解 | Matlab实现CEEMDANPE自适应噪声完备集合经验模态分解排列熵计算效果一览基本介绍程序设计参考资料 效果一览 基本介绍 CEEMDANPE自适应噪声完备集合经验模态分解排列熵计算 运行环境m…

第六回 花和尚倒拔垂杨柳 豹子头误入白虎堂-安装服务器管理面板AMH和cyberpanel

且说鲁智深踏入菜园之时&#xff0c;二三十个泼皮无赖正聚集于此&#xff0c;他们手持果盒酒礼&#xff0c;脸上嬉皮笑脸&#xff0c;口称前来庆贺。然而&#xff0c;当这群人走到粪窖边缘&#xff0c;打头阵的张三和李四竟妄想搬动鲁智深&#xff0c;结果却被他轻描淡写地一脚…

element中表格组件的row-class-name和class-name属性的使用以及无效处理

1.这两个属性的使用&#xff0c;row-class-name用在el-table标签上&#xff0c;class-name用在el-table-column标签上。两个属性即可绑定类名也可绑定函数 <!-- 这里是绑定函数&#xff0c;也可以绑定类名 --> <el-table :data"tableData" selection-chang…

【C++】string的基本使用

从这篇博客开始&#xff0c;我们的C部分就进入到了STL&#xff0c;STL的出现可以说是C发展历史上非常关键的一步&#xff0c;自此C和C语言有了较为明显的差别。那么什么是STL呢&#xff1f; 后来不断的演化&#xff0c;发展成了知名的两个版本&#xff0c;一个叫做P.J.版本&am…

Liunx:线程控制

目录 创建线程&#xff1a;pthread_create(); 线程等待&#xff1a;pthread_join(); 线程退出&#xff1a;pthread_exit(); 线程取消&#xff1a;pthread_cancel() 说线程的时候说过&#xff0c;liunx没有选择单独定义线程的数据结构和适配算法&#xff0c;而是用轻量级进程…

关于java的继承

关于java的继承 我们在上一篇文章中&#xff0c;了解到了封装&#xff0c;我们本篇文章来介绍一下面向对象的第二大特点&#xff0c;继承&#xff0c;还是遵循结合现实生活中的实际情况&#xff0c;理解着去学习&#xff0c;能更好的加深印象&#x1f600;。 一、继承 继承的…