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 小时前
01-spring security认证笔记
java·笔记·spring
小二·4 小时前
java基础面试题笔记(基础篇)
java·笔记·python
wusong9997 小时前
mongoDB回顾笔记(一)
数据库·笔记·mongodb
猫爪笔记7 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
Resurgence037 小时前
【计组笔记】习题
笔记
pq113_68 小时前
ftdi_sio应用学习笔记 3 - GPIO
笔记·学习·ftdi_sio
爱米的前端小笔记8 小时前
前端八股自学笔记分享—页面布局(二)
前端·笔记·学习·面试·求职招聘
寒笙LED11 小时前
C++详细笔记(六)string库
开发语言·c++·笔记
岳不谢11 小时前
VPN技术-VPN简介学习笔记
网络·笔记·学习·华为
红色的山茶花13 小时前
YOLOv8-ultralytics-8.2.103部分代码阅读笔记-block.py
笔记·深度学习·yolo