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

相关推荐
erzong2312 分钟前
Linux操作系统:基于环形队列&信号量实现多生产者多消费者的简易模型
linux·运维·服务器
丑梨数据6 分钟前
法律合同知识库怎么搭:从图片压缩到私有化 RAG 的工程笔记
开发语言·笔记·c#
小羊没烦恼!7 分钟前
TypedSql:在 C# 类型系统上实现一个 SQL 查询引擎
java·linux·运维·服务器·开发语言·数据库·mysql
2401_8685347815 分钟前
国家东数西算纵深推进的算力感知网络(APN6/算网一体)架构规划与设计
服务器·网络
快乐的韭菜根根18 分钟前
SLURM配置服务器一
运维·服务器
极光通讯22 分钟前
国产存储替代进展:长鑫DDR5与长江存储企业级SSD的适配现状
服务器·数据库·内存
张小姐的猫44 分钟前
【MySQL】表的约束
android·linux·服务器·数据库·c++·mysql·adb
1-1=01 小时前
.NET Core 输出日志
c#·.net·.netcore
guo_wen_qiang1 小时前
mongodb集群模式的原理
服务器·数据库·mongodb
曹牧1 小时前
C#里引用ActiveX控件
开发语言·c#