CommunityToolkit.Mvvm提供了强大的数据验证支持,通过实现INotifyDataErrorInfo接口,可以轻松实现属性验证、跨属性验证等功能。本文将详细介绍如何在WinForm应用中使用这些验证特性。
在MVVM模式中,验证通常发生在ViewModel层。CommunityToolkit.Mvvm提供了以下几种验证方式:
XML<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />

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("保存成功!");
}
}
}
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是CommunityToolkit.Mvvm提供的基类,它实现了:
这些接口使得验证功能可以无缝集成到MVVM架构中。
[NotifyDataErrorInfo]: 启用属性验证通知[Required]: 必填验证[StringLength]: 字符串长度验证[Range]: 数值范围验证[EmailAddress]: 电子邮件格式验证除了使用内置的验证特性,还可以通过以下方式实现自定义验证:
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 这个方法是关键
CommunityToolkit.Mvvm的验证支持为WinForm应用提供了强大而灵活的数据验证机制。通过属性验证、自定义验证规则和错误通知机制,可以轻松实现复杂的验证需求。结合MVVM模式,使得代码更加清晰、可维护。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!