一、MVVM的属性验证案例
Toolkit.Mvvm框架中的ObservableValidator类,提供了属性验证功能,可以使用我们熟悉的验证特性对属性的值进行验证,并将错误属性提取和反馈给UI层。以下案例实现对UI层的姓名和年龄两个输入框,进行表单提交验证。实现效果如下所示:
1、View
<ContentPage ......> <ContentPage.BindingContext> <vm:MainPageViewModel /> </ContentPage.BindingContext> <ScrollView> <VerticalStackLayout> <!--姓名输入框及其验证信息--> <Entry Text="{Binding Name}" Placeholder="请输入姓名" /> <Label Text="{Binding NameErrorMsg}" TextColor="Red" /> <!--年龄输入框及其验证信息--> <Entry Text="{Binding Age}" Placeholder="请输入年龄" /> <Label Text="{Binding AgeErrorMsg}" TextColor="Red" /> <!--汇总验证信息--> <Label Text="{Binding AllErrorMsg}" TextColor="Red" /> <!--提交按钮验证表单字段--> <Button Command="{Binding SubmitNameCommand}" Text="单独验证姓名字段" /> <Button Command="{Binding SubmitAgeCommand}" Text="单独验证年龄字段" /> <Button Command="{Binding SubmitAllCommand}" Text="验证所有字段" /> </VerticalStackLayout> </ScrollView> </ContentPage>
2、ViewModel
public partial class MainPageViewModel:ObservableValidator { /* ========定义Name和Age属性 */ [ObservableProperty] [Required(ErrorMessage = "姓名必填!")] //框架内置的验证特性 [MinLength(2,ErrorMessage = "最少2个字符")] //框架内置的验证特性 [MaxLength(10,ErrorMessage = "最多10个字符")] //框架内置的验证特性 private string name; [ObservableProperty] [CustomValidation(typeof(MainPageViewModel),nameof(ValidateAge1))] //使用通过静态方法定义的自定义验证特性 [ValidateAge2(1,17)] //使用通过验证类的自定义验证特性 private int age; /* ========定义姓名、年龄以及所有字段的报错信息,通过Binding反馈给UI层 */ [ObservableProperty] private string nameErrorMsg; //姓名验证报错信息 [ObservableProperty] private string ageErrorMsg; //年龄验证报错信息 [ObservableProperty] private string allErrorMsg; //所有属性验证报错信息 /* ========以下命令使用ObservableValidator对象提供的方法或属性,对Name属性进行检验 * 方法ValidateProperty(属性值,"属性名"),对特定属性执行校验 * 属性HasErrors,判断是否有检验错误 * 方法GetErrors("属性名"),获得ValidationResult对象,此对象的ErrorMessage属性为错误信息 */ [RelayCommand] private void SubmitName() { ValidateProperty(Name,"Name"); if (HasErrors) { NameErrorMsg = string.Join(Environment.NewLine, GetErrors("Name").Select(e => e.ErrorMessage)); } else { NameErrorMsg = string.Empty; } } //========同上 [RelayCommand] private void SubmitAge() { //验证Age属性, ValidateProperty(Age,"Age"); if (HasErrors) { AgeErrorMsg = string.Join(Environment.NewLine, GetErrors("Age").Select(e => e.ErrorMessage)); } else { AgeErrorMsg = string.Empty; } } /* ========以下命令校验所有属性 * 方法ValidateAllProperties(),会检验所有属性 * 属性HasErrors,判断是否有检验错误 * 方法GetErrors(),获得所有ValidationResult对象,此对象的ErrorMessage属性,获取所有校验错误 */ [RelayCommand] private void SubmitAll() { ValidateAllProperties(); if (HasErrors) { AllErrorMsg = string.Join(Environment.NewLine, GetErrors().Select(e => e.ErrorMessage)); } else { AllErrorMsg = string.Empty; } } /* ========自定义验证特性方法①:静态方法 * 返回值为ValidationResult,如果验证成功,返回ValidateResult.Success,如果失败,则返回new("报错信息") * 第一个参数为待验证的属性,第二个参数为参证上下文ValidationContext,可以获得当前实例、成员等信息 * 如通过以下代码【(MainPageViewModel)context.ObjectInstance】获得当前对象 */ public static ValidationResult ValidateAge1(int age, ValidationContext context) { if (age >= 18 && age <= 100) { return ValidationResult.Success; } return new("年龄最小18岁最大100岁"); } } /* ========自定义验证特性方式②: * 定义继承自ValidationAttribute的验证类。推荐方式,可以重用。 * 定义两个属性MaxAge和MinAge,使用特性时,通过特性参数赋值 * 必须重写IsValid方法,如果验证成功,返回ValidationResult.Success。如果失败,则返回new("错误信息") */ public sealed class ValidateAge2Attribute : ValidationAttribute { //属性MaxAge和MinAge,将通过特性参数赋值 public int MaxAge { get; } public int MinAge { get; } public ValidateAge2Attribute(int maxAge, int minAge) { MaxAge = maxAge; MinAge = minAge; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { int age = (int)value; if (age >= MinAge && age <= MaxAge) { return ValidationResult.Success; } return new($"年龄最小{MinAge},最大{MaxAge}"); } }
3、基本实现说明:
- UI层的表单字段、错误信息字段,与ViewModel的属性绑定。
- ViewModel派生自ObservableValidator(ObservableValidator派生自ObservableObject,也具有绑定功能)。
- 待验证属性,使用验证特性标注。验证特性既可以使用框架内置的特性(推荐),也可以自定义验证特性。自定义验证特性的方式有两种:静态验证方法和验证类特性。
- UI层绑定命令,在命令中执行属性值检验,并提取校验错误信息赋值给错误信息字段。
- ObservableValidator提供的几个方法和属性:ValidateProperty方法-校验指定属性、ValidateAllProperties方法-校验所有属性、HasErrors属性-判断是否有校验错误、GetErrors方法-获取指定属性或所有属性的校验错误信息。
二、常用的验证特性:可直接查看文档
标签:string,MVVM,验证,ErrorMessage,特性,private,MAUI,2.5,属性 From: https://www.cnblogs.com/functionMC/p/17092644.html