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() {

        }
       
    }
}

结果如下:

可实时校验。

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

相关推荐
Yawesh_best21 分钟前
思源笔记轻松连接本地Ollama大语言模型,开启AI写作新体验!
笔记·语言模型·ai写作
CXDNW2 小时前
【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
网络·笔记·http·面试·https·http2.0
使者大牙2 小时前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型
ssf-yasuo2 小时前
SPIRE: Semantic Prompt-Driven Image Restoration 论文阅读笔记
论文阅读·笔记·prompt
ajsbxi2 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
TeYiToKu3 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws3 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
cuisidong19974 小时前
5G学习笔记三之物理层、数据链路层、RRC层协议
笔记·学习·5g
乌恩大侠4 小时前
5G周边知识笔记
笔记·5g
咔叽布吉6 小时前
【论文阅读笔记】CamoFormer: Masked Separable Attention for Camouflaged Object Detection
论文阅读·笔记·目标检测