编辑
2025-11-25
C#
00

目录

简介
基础知识
实现示例
安装必要的NuGet包
创建ViewModel
3.3 创建WinForm窗体
验证特性说明
ObservableValidator基类
验证特性
4.3 自定义验证
6. 总结

简介

CommunityToolkit.Mvvm提供了强大的数据验证支持,通过实现INotifyDataErrorInfo接口,可以轻松实现属性验证、跨属性验证等功能。本文将详细介绍如何在WinForm应用中使用这些验证特性。

基础知识

在MVVM模式中,验证通常发生在ViewModel层。CommunityToolkit.Mvvm提供了以下几种验证方式:

  • 属性级别验证
  • 对象级别验证
  • 自定义验证规则

实现示例

安装必要的NuGet包

XML
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />

image.png

创建ViewModel

C#
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace App14 { public partial class UserViewModel : ObservableValidator { // 用户名属性,必填且长度在3-20之间 [ObservableProperty] [NotifyDataErrorInfo] [Required(ErrorMessage = "用户名不能为空")] [StringLength(20, MinimumLength = 3, ErrorMessage = "用户名长度必须在3-20个字符之间")] private string? _userName; // 年龄属性,必须大于0且小于120 [ObservableProperty] [NotifyDataErrorInfo] [Range(1, 120, ErrorMessage = "年龄必须在1-120之间")] private int _age; // 电子邮件属性,必须符合邮件格式 [ObservableProperty] [NotifyDataErrorInfo] [Required(ErrorMessage = "邮箱不能为空")] [EmailAddress(ErrorMessage = "请输入有效的邮箱地址")] private string? _email; // 保存命令 [RelayCommand] private void Save() { // 在保存前验证所有属性 ValidateAllProperties(); if (HasErrors) { MessageBox.Show("请修正所有错误后再保存!"); return; } // 执行保存逻辑 MessageBox.Show("保存成功!"); } } }

3.3 创建WinForm窗体

C#
namespace App14 { public partial class Form1 : Form { private readonly UserViewModel _viewModel; public Form1() { InitializeComponent(); // 初始化ViewModel _viewModel = new UserViewModel(); // 设置数据绑定 SetupBindings(); // 设置错误提供程序 SetupValidation(); } private void SetupBindings() { // 用户名绑定 txtUserName.DataBindings.Add(new Binding("Text", _viewModel, nameof(_viewModel.UserName), true, DataSourceUpdateMode.OnPropertyChanged)); // 年龄绑定 txtAge.DataBindings.Add(new Binding("Text", _viewModel, nameof(_viewModel.Age), true, DataSourceUpdateMode.OnPropertyChanged)); // 邮箱绑定 txtEmail.DataBindings.Add(new Binding("Text", _viewModel, nameof(_viewModel.Email), true, DataSourceUpdateMode.OnPropertyChanged)); // 保存按钮绑定 btnSave.Click += (s, e) => _viewModel.SaveCommand.Execute(null); } private void SetupValidation() { // 创建错误提供程序 var errorProvider = new ErrorProvider(); // 监听ViewModel的错误变化 _viewModel.ErrorsChanged += (s, e) => { if (e.PropertyName == nameof(_viewModel.UserName)) { var errors = _viewModel.GetErrors(nameof(_viewModel.UserName)); errorProvider.SetError(txtUserName, errors.FirstOrDefault()?.ErrorMessage); } else if (e.PropertyName == nameof(_viewModel.Age)) { var errors = _viewModel.GetErrors(nameof(_viewModel.Age)); errorProvider.SetError(txtAge, errors.FirstOrDefault()?.ErrorMessage); } else if (e.PropertyName == nameof(_viewModel.Email)) { var errors = _viewModel.GetErrors(nameof(_viewModel.Email)); errorProvider.SetError(txtEmail, errors.FirstOrDefault()?.ErrorMessage); } }; } } }

验证特性说明

ObservableValidator基类

ObservableValidator是CommunityToolkit.Mvvm提供的基类,它实现了:

  • INotifyPropertyChanged
  • INotifyDataErrorInfo
  • IValidatableObject

这些接口使得验证功能可以无缝集成到MVVM架构中。

验证特性

  • [NotifyDataErrorInfo]: 启用属性验证通知
  • [Required]: 必填验证
  • [StringLength]: 字符串长度验证
  • [Range]: 数值范围验证
  • [EmailAddress]: 电子邮件格式验证

4.3 自定义验证

除了使用内置的验证特性,还可以通过以下方式实现自定义验证:

C#
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace App14 { public partial class UserViewModel : ObservableValidator { // 用户名属性,必填且长度在3-20之间 [ObservableProperty] [NotifyDataErrorInfo] [Required(ErrorMessage = "用户名不能为空")] [StringLength(20, MinimumLength = 3, ErrorMessage = "用户名长度必须在3-20个字符之间")] private string? _userName; // 年龄属性,必须大于0且小于120 [ObservableProperty] [NotifyDataErrorInfo] [CustomValidation(typeof(UserViewModel), nameof(ValidateAge))] [Range(1, 120, ErrorMessage = "年龄必须在1-120之间")] private int _age; // 电子邮件属性,必须符合邮件格式 [ObservableProperty] [NotifyDataErrorInfo] [EmailAddress(ErrorMessage = "请输入有效的邮箱地址")] private string? _email; public static ValidationResult ValidateAge(int age, ValidationContext context) { // 获取当前 ViewModel 实例 var instance = (UserViewModel)context.ObjectInstance; // 如果年龄小于18岁,邮箱可以为空 if (age < 18) { return ValidationResult.Success; } // 如果年龄大于等于18岁,检查邮箱是否为空 else if (string.IsNullOrWhiteSpace(instance.Email)) { return new ValidationResult("成年人必须填写邮箱地址"); } return ValidationResult.Success; } // 保存命令 [RelayCommand] private void Save() { // 在保存前验证所有属性 ValidateAllProperties(); if (HasErrors) { MessageBox.Show("请修正所有错误后再保存!"); return; } // 执行保存逻辑 MessageBox.Show("保存成功!"); } // 重置命令 [RelayCommand] private void Reset() { UserName = string.Empty; Age = 0; Email = string.Empty; // 清除所有验证错误 ClearErrors(); } // 构造函数 public UserViewModel() { // 初始化属性 _age = 0; PropertyChanged += (sender, args) => { // 当任何属性变化时触发验证 ValidateAllProperties(); }; } } }

ValidateAge 这个方法是关键

6. 总结

CommunityToolkit.Mvvm的验证支持为WinForm应用提供了强大而灵活的数据验证机制。通过属性验证、自定义验证规则和错误通知机制,可以轻松实现复杂的验证需求。结合MVVM模式,使得代码更加清晰、可维护。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!