WINUI——自定义验证特性

背景

在开发过程中验证数据是否符合要求是经常遇到的,如IP的验证、邮箱的验证、电话号码的验证等等。C#中System.ComponentModel.DataAnnotations 命名空间下提供了一些常用特性用于数据的验证,常用的如Required、MaxLength、MinLength、Key、NotMapped等等,满足了多数时候的使用需求,但对于一些场景,还不能满足项目需要的。这时就需要自定义相应的验证特性,以满足工程需要。

开发环境

WIN11

VS2022

MVVM Toolkit7.1.2

.net core6

自定义验证特性

自定义方法如下

  1. 添加AttributeUsage特性。
  2. 继承于ValidationAttribute,重写IsValid方法。

以自定义端口验证特性进行详细的说明:

cs 复制代码
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class PortNumberAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            return new ValidationResult("端口号不能为空");
        }

        var portString = value.ToString();

        if (!int.TryParse(portString, out int port))
        {
            return new ValidationResult("请输入有效的端口号");
        }

        if (port < 0 || port > 65535)
        {
            return new ValidationResult("端口号必须在0到65535之间");
        }

        // 可以在这里检查端口是否已被使用等  

        return ValidationResult.Success;
    }
}

注意:

AttributeUsage中添加了AttributeTargets.Property,它指此验证特性可用于Property(属性)上;

AllowMultiple = false 表示在同一属性上不可多次使用此自定义验证特性;

Inherited = true 表示这个验证特性是可以继承的。

VM使用如下

使用方法如下(以下代码使用了MVVM Toolkit,整个VM继承于它的ObservableValidator以进行数据验证,因此SetProperty与GetErrors可直接使用):

cs 复制代码
        [ObservableProperty]
        private string localPortErrorMessage;
        [PortNumber(ErrorMessage = "请输入有效的端口号")]
        public string LocalTerminalPort
        {
            get => localTerminalPort;
            set
            {
                SetProperty(ref localTerminalPort, value, true);
                LocalPortErrorMessage = GetErrors(nameof(LocalTerminalPort)).Cast<ValidationResult>().FirstOrDefault()?.ErrorMessage ?? string.Empty;
            }
        }

上述代码中的LocalPortErrorMessage即是出错的报错信息,绑定此信息到xaml上,填写出错时即可及时看到出错信息。

在VM中若有多个验证的情况下,一个不满足时就不请允许进行后续操作,这时可利用ObservableValidator 提供的**HasErrors**进行相应判断。

x:Bind属性注意事项

xaml中绑定时需要注意,由于验证特性是在set时进行验证,然后设置相应的错误信息,也就是说需要验证的属性变化时就要立马验证,如果使用x:Bind进行验证时,则需要设置Mode=TwoWay且UpdateSourceTrigger=PropertyChanged,即如下所示:

XML 复制代码
 <TextBox
        Name="password"
        Width="500"
        Height="66"
        MaxLength="10"
        Text="{x:Bind VM.Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

若使用x:Bind不设置Mode=TwoWay,则会报下述错误:

Invalid binding assignment : 'UpdateSourceTrigger' may only be used with binding 'Mode=TwoWay'

若使用x:Bind不设置UpdateSourceTrigger=PropertyChanged,则会导致属性更新时不会及时通知VM,也就不会马上进行数据验证。

使用Bing暂未发现上述问题。

参考连接

https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=net-8.0

ObservableValidator Class (CommunityToolkit.Mvvm.ComponentModel) | Microsoft Learn

System.ComponentModel.DataAnnotations 命名空间 | Microsoft Learn

相关推荐
古城小栈1 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
程序猿阿伟1 天前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome
凡人叶枫1 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
AC赳赳老秦1 天前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
2601_962072551 天前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
java_cj1 天前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
lsyeei1 天前
linux 系统目录详解
linux·运维·服务器
森G1 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt
张飞飞飞飞飞1 天前
Tmux命令使用教程
linux·服务器·ubuntu
森G1 天前
77、线程池原理和实现------服务器源码解析----云视频服务项目
服务器·c++·qt