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

相关推荐
人工智能AI技术6 分钟前
【C#程序员入门AI】本地大模型落地:用Ollama+C#在本地运行Llama 3/Phi-3,无需云端
人工智能·c#
AI逐月1 小时前
tmux 常用命令总结:从入门到稳定使用的一篇实战博客
linux·服务器·ssh·php
想逃离铁厂的老铁1 小时前
Day55 >> 并查集理论基础 + 107、寻找存在的路线
java·服务器
舰长1152 小时前
linux 实现文件共享的实现方式比较
linux·服务器·网络
路由侠内网穿透.2 小时前
本地部署智能家居集成解决方案 ESPHome 并实现外部访问( Linux 版本)
linux·运维·服务器·网络协议·智能家居
树℡独2 小时前
ns-3仿真之应用层(三)
运维·服务器·ns3
VekiSon2 小时前
Linux内核驱动——基础概念与开发环境搭建
linux·运维·服务器·c语言·arm开发
skywalk81633 小时前
尝试在openi启智社区的dcu环境安装ollama最新版0.15.2(失败)
linux·运维·服务器·ollama
看我干嘛!3 小时前
第三次python作业
服务器·数据库·python
Andy Dennis4 小时前
FTP局域网功能小网站V2_2
服务器·flask·html5