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

相关推荐
non-action_pilgrim10 分钟前
《小坦克大战小怪兽》小游戏实战四:基于 protoactor-go 的游戏服务器框架与状态持久化实战
服务器·游戏·golang
落羽的落羽20 分钟前
【算法札记】练习 | Week1
linux·服务器·c++·人工智能·python·算法·机器学习
qq_4542450320 分钟前
图数据标准化与智能去重框架:设计与实现解析
数据结构·架构·c#·图论
王琦031824 分钟前
第十章 管理Linux的联网
linux·服务器·php
Run_Teenage28 分钟前
Linux:进程间通信-System V 共享内存
linux·运维·服务器
木子欢儿31 分钟前
Ubuntu 24.04 执行超微服务器 JNLP 程序
linux·运维·服务器·ubuntu
柠檬味的Cat32 分钟前
腾讯云轻量服务器一键部署OpenClaw教程
服务器·腾讯云
CSharp精选营35 分钟前
C# 如何减少代码运行时间:7 个实战技巧
性能优化·c#·.net·技术干货·实战技巧
还在忙碌的吴小二39 分钟前
在 Mac 上安装并通过端口调用 Chrome DevTools MCP Server(谷歌官方 MCP 服务器)
服务器·前端·chrome·macos·chrome devtools
_下雨天.6 小时前
LVS负载均衡
服务器·负载均衡·lvs