CommunityToolkit.Mvvm笔记---ObservableValidator

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

平台 API: ObservableValidatorObservableObject

工作原理(摘抄自官网)

ObservableValidator 包含以下主要功能:

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

xaml试图

cs 复制代码
<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:

cs 复制代码
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() {

        }
       
    }
}

结果如下:

可实时校验。

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

相关推荐
饕餮争锋3 小时前
设计模式笔记_创建型_建造者模式
笔记·设计模式·建造者模式
萝卜青今天也要开心4 小时前
2025年上半年软件设计师考后分享
笔记·学习
吃货界的硬件攻城狮4 小时前
【STM32 学习笔记】SPI通信协议
笔记·stm32·学习
蓝染yy4 小时前
Apache
笔记
lxiaoj1115 小时前
Python文件操作笔记
笔记·python
半导体守望者6 小时前
ADVANTEST R4131 SPECTRUM ANALYZER 光谱分析仪
经验分享·笔记·功能测试·自动化·制造
啊我不会诶7 小时前
倍增法和ST算法 个人学习笔记&代码
笔记·学习·算法
逼子格7 小时前
振荡电路Multisim电路仿真实验汇总——硬件工程师笔记
笔记·嵌入式硬件·硬件工程·硬件工程师·硬件工程师真题·multisim电路仿真·震荡电流
一条破秋裤8 小时前
一份多光谱数据分析
笔记·数据挖掘·数据分析
zstar-_8 小时前
【算法笔记】6.LeetCode-Hot100-链表专项
笔记·算法·leetcode