CommunityToolkit.Mvvm笔记---ObservableValidator

ObservableValidator 是实现 INotifyDataErrorInfo 接口的基类,它支持验证向其他应用程序模块公开的属性。 它也继承自 ObservableObject,因此它还可实现 INotifyPropertyChanged 和 INotifyPropertyChanging。 它可用作需要支持属性更改通知和属性验证的各种对象的起点。

平台 API:ObservableValidator、ObservableObject

工作原理(摘抄自官网)

ObservableValidator 包含以下主要功能:

  • 它提供对 INotifyDataErrorInfo 的基本实现,从而公开 ErrorsChanged 事件和其他必要的 API。
  • 它提供一系列额外的 SetProperty 重载(ObservableObject 基类提供的重载除外),这些重载提供在更新属性值之前自动验证属性和引发必要事件的功能。
  • 它公开了许多 TrySetProperty 重载,这些重载类似于 SetProperty 但仅在验证成功时更新目标属性,并在出错时返回生成的错误以供进一步检查。
  • 它公开了 ValidateProperty 方法,这对于手动触发对特定属性的验证非常有用,以防其值尚未更新,但其验证依赖于已更新的另一个属性的值。
  • 它公开了 ValidateAllProperties 方法,这会自动执行对当前实例中所有公共实例属性的验证,前提是它们至少应用了一个 [ValidationAttribute]。
  • 它公开了 ClearAllErrors 方法,该方法在重置绑定到用户可能需要再次填充的某个表单的模型时非常有用。
  • 它提供许多构造函数,这些函数允许传递不同的参数来初始化将用于验证属性的 ValidationContext 实例。 使用可能需要其他服务或选项才能正常工作的自定义验证特性时,这尤其有用。
具体实例

xaml试图

<Page x:Class="Event.Views.Pages.RegistrationForm"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:Event.Views.Pages"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="RegistrationForm">
    <Page.Resources>
        <Style TargetType="TextBox">
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <StackPanel>
                            <AdornedElementPlaceholder />
                            <ItemsControl ItemsSource="{Binding}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock
                                           Foreground="Red"
                                           Text="{Binding ErrorContent}" />
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>
    <Grid>
        <StackPanel>
            <TextBox Width="150" Height="30" VerticalContentAlignment="Center" Margin="0 10 0 0 "  Text="{Binding Email,UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=true, ValidatesOnDataErrors=true}" 
                    ></TextBox>
            
            <!--<Label Content="{Binding Path=(Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Self}}"></Label>-->
            <TextBox Width="150" Height="30" VerticalContentAlignment="Center" Margin="0 20 0 0 " Text="{Binding Name,UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=true, ValidatesOnDataErrors=true}" ></TextBox>
            <TextBox Width="150" Height="30" VerticalContentAlignment="Center" Margin="0 20 0 0"
                     Text="{Binding Age,UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=true, ValidatesOnDataErrors=true}"></TextBox>
            <Button Width="150" Height="30" Margin="0 20 0 0" Command="{Binding SubmitCommand}">Submit</Button>
        </StackPanel>
        
    </Grid>
</Page>

创建viewModel:

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Event.Views.Pages;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Event.ViewModels.Pages
{
    public partial  class RegistrationFormViewModel : ObservableValidator
    {
        private string _email;

        //[ObservableProperty]
        [Required(ErrorMessage = "Email is required")]
        [EmailAddress(ErrorMessage = "Invaid email address")]
        public string Email
        {
            get => _email;
            set => SetProperty(ref _email, value, true);
        }

        private string _name;
        [Required(ErrorMessage ="name不可为空")]
        [MinLength(2,ErrorMessage ="name长度不小于2")]
        [MaxLength(30,ErrorMessage ="name长度不大于30")]
        //
        public string Name
        {
            get => _name;
            set => SetProperty(ref _name, value, true);

        }
        private int _age;
        [CustomValidation(typeof(RegistrationFormViewModel), nameof(ValidateAge1))]
        public int Age
        {
            get => (int)_age;
            set => SetProperty(ref _age, value, true);
        }

        public static ValidationResult ValidateAge1(int age, ValidationContext context)
        {
            if (age >= 18 && age <= 100)
            {
                return ValidationResult.Success;
            }
            return new("年龄最小18岁最大100岁");

        }
        [RelayCommand]
        public void Submit()
        {
            ValidateAllProperties(); // Validates all properties with validation attributes

            if (HasErrors)
            {
                // Handle validation errors
                // For example, inform the user to correct the errors
                MessageBox.Show("error");
            }
            else
            {
                // Process the data as there are no validation errors
                MessageBox.Show("right");
            }
        }
        public RegistrationFormViewModel() {

        }
       
    }
}

 结果如下:

 可实时校验。

上述例子中有内置验证,也有自定义验证,也可参考官网。

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

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

相关文章

Redis中的Lua脚本(五)

Lua脚本 脚本复制 复制EVALSHA命令 EVALSHA命令式所有与Lua脚本有关的命令中&#xff0c;复制操作最复杂的一个&#xff0c;因为主服务器与从服务器载入Lua脚本的情况可能有所不同&#xff0c;所以主服务器不能像复制EVAL命令、SCRIPT LOAD命令或者SCRIPT FLUSH命令那样&…

2024 Polkadot Decoded 大会亮点前瞻,立即预定参会席位

原文&#xff1a;https://medium.com/polkadotnetwork/polkadot-decoded-2024-uniting-innovators-in-blockchain-technology-75fc3d8e93fe 作者&#xff1a;Polkadot 编译&#xff1a;OneBlock Polkadot 生态宣布他们的旗舰活动 —— Polkadot Decoded 将再次举行&#xff…

跟TED演讲学英文:How AI could empower any business by Andrew Ng

How AI could empower any business Link: https://www.ted.com/talks/andrew_ng_how_ai_could_empower_any_business Speaker: Andrew Ng Date: April 2022 文章目录 How AI could empower any businessIntroductionVocabularyTranscriptSummary后记 Introduction Expensiv…

von Mises-Fisher Distribution (Appendix 2)

5.3 Fast Python Sampler of the von Mises Fisher Distribution [3] 从论文中 p r o c e d u r e A n g l e G e n e r a t o r ( d , κ ) procedure~AngleGenerator(d, κ) procedure AngleGenerator(d,κ) 中的变换来看, 假设 y ∼ B e ( m − 1 2 , m − 1 2 ) y \sim …

Linux【实战】—— LAMP环境搭建 部署网站

目录 一、介绍 1.1什么是LAMP&#xff1f; 1.2LAMP的作用 二、部署静态网站 2.1 虚拟主机&#xff1a;一台服务器上部署多个网站 2.1.1 安装Apache服务 2.1.2 防火墙配置 2.1.3 准备网站目录 2.1.4 创建网站的配置文件 2.1.5 检查配置文件是否正确 2.1.6 Linux客户端…

【华为 ICT HCIA eNSP 习题汇总】——题目集17

1、以下哪项不属于网络层安全威胁&#xff1f; A、DDos攻击 B、钓鱼攻击 C、IP Spoofing D、IP地址扫描 考点&#xff1a;网络安全 解析&#xff1a;&#xff08;B&#xff09; 钓鱼攻击通常被认为是应用层的安全威胁&#xff0c;也有在网络层进行伪装实施钓鱼攻击&#xff0c;…

TCP/IP常用协议栈图解

1.引言 最近看了一些计算机网络的课程&#xff0c;总结借鉴了一些TCP/IP常用协议&#xff0c;罗列在以下图中&#xff0c;以便有一个整体观。 2.图解 先上图 3.总结 TCP/IP协议是实际用的计算机网络通信的标准协议栈&#xff0c;自上而下分为应用层&#xff0c;传输层&#xf…

关于二级指针void**的一点问题与思考

前言 这两天写一个高并发内存池的项目时&#xff0c;遇到了一个关于二级指针的问题&#xff0c;剖析清楚后发觉有必要记录一下&#xff0c;这让我加深了对于C/C中指针的理解&#xff08;果然学到老活到老&#xff09;。 问题的分析 在我的内存池项目中&#xff0c;有一个需求…

【TEE论文】IceClave: A Trusted Execution Environment for In-Storage Computing

摘要 使用现代固态硬盘&#xff08;SSD&#xff09;的存储中计算使开发人员能够将程序从主机转移到SSD上。这被证明是缓解I/O瓶颈的有效方法。为了促进存储中计算&#xff0c;已经提出了许多框架。然而&#xff0c;其中很少有框架将存储中的安全性作为首要任务。具体而言&…

WebLogic 数据源连接泄露

编码时&#xff0c;有时会忘记释放使用的数据源连接&#xff0c;造成连接泄露&#xff0c;没有连接资源可用。 现象 java.sql.SQLException: Cannot obtain XAConnectionat weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1691)at weblogic.jdbc.jta.…

ssm062会员管理系统+jsp

会员管理系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于会员管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了会员管理系统&#xff0c;它彻底改…

Java项目引入log4j2

log4j2 单独使用 引入依赖 <dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.14.0</version></dependency><dependency><groupId>o…

[管理者与领导者-174] :人际网络-1- 网络概述,是由一个个人组成的网络,每个节点是“人”

目录 一、数据通信网络 二、移动通信网络 三、人际网络 四、计算机网络与人际网络的比较 五、人际网络中节点-人的分层架构 5.1 人&#xff08;节点&#xff09;的分层架构&#xff1a;个体生理、个体心理、人际关系、社会功能 5.2 什么是人性 5.3 人性的特点 5.3 人性…

智能化新浪潮:国产智能体势在必行,一探究竟!

回顾之前的文章 GPTs大爆发&#xff1a;我的智能助手累计使用71k&#xff0c;荣登全球排名79&#xff0c;我们已经见证了智能助手的强劲增长势头。今天&#xff0c;我兴奋地分享一个新的里程碑&#xff1a;我的GPTs使用量已经突破10万次&#xff0c;排名再次提升&#xff01; 接…

盲人出行新助手:无障碍技术的进步

作为一名资深记者&#xff0c;我始终关注着社会弱势群体的生活权益&#xff0c;尤其是对于视障人士这一特殊群体。在科技日新月异的今天&#xff0c;我们欣喜地看到&#xff0c;盲人无障碍设施这一概念正在以更为先进、人性化的形式实现落地&#xff0c;其中&#xff0c;一款名…

与上级意见不合时如何恰当地表达自己的观点?

在工作中与上级意见不合时&#xff0c;恰当表达自己的观点并寻求共识是一个需要谨慎处理的问题。以下是一些建议&#xff1a; 1. **尊重与礼貌**&#xff1a;在任何情况下&#xff0c;都应保持对上级的尊重和礼貌。即使在意见不合时&#xff0c;也要避免情绪化&#xff0c;保持…

简单二分应用

思路&#xff1a;首先二分需要数列有二分性&#xff0c;我们要对数列排序&#xff0c;然后二分距离&#xff0c;直到出现一个距离可以满足&#xff0c;点数大于等于k。 代码&#xff1a; void solve(){int n, q;cin >> n >> q;vector<int>a(n);for(int i …

代码随想录:二叉树11-12

目录 222.完全二叉树的节点个数 题目 代码&#xff08;层序迭代&#xff09; 代码&#xff08;后序递归&#xff09; 代码&#xff08;满二次树递归&#xff09; 总结 110.平衡二叉树 题目 代码&#xff08;后序递归&#xff09; 代码&#xff08;层序迭代&#xff0…

设置表格高度后,数值改变但实际不变

1.选中表格 2.点击“开始”——>“段落设置”的选项启动按钮&#xff0c;设置为单倍行距 3.可以看到&#xff0c;表格的行高被调小了。

如何高效建立企业绩效评估体系?这家世界500强企业用BI工具这么做

在目前经济下行&#xff0c;竞争激烈&#xff0c;向精细化管理要效益的社会背景下&#xff0c;如何对资金结算部门做好绩效管理&#xff0c;以保障组织的正常运作&#xff0c;是各大企业面对的重要痛点。 本文将基于某世界500强公司的财务共享资金结算部门的绩效管理办法&…