Avalonia数据有效性验证与手动设置错误

示例代码:https://github.com/bodong1987/AvaloniaSamples/tree/main/AvaloniaDataValidation

官方文档:https://docs.avaloniaui.net/docs/data-binding/data-validation

      Avalonia通过插件来实现数据校验,有三种方法。

1. 直接在属性的set中抛出异常。(个人不推荐这种方案)

2. 使用DataAnnotations特性(Attributes)(个人推荐这种方法)

3. 实现INotifyDataErrorInfo接口

     下面是一个简单的数据校验的示例,主要使用了异常方案和DataAnnotations方案:

复制代码
using ReactiveUI;
using System;
using System.ComponentModel.DataAnnotations;

namespace AvaloniaDataValidation.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        string EmailCore = "";

        [EmailAddress]
        public string Email
        {
            get => EmailCore;
            set => this.RaiseAndSetIfChanged(ref EmailCore, value);
        }

        public string[] CombItems => new string[]
        {
            "C",
            "C++",
            "C#",
        };

        string ProgramLanguageCore = "C";

        [LaungageValidation]
        public string ProgramLanguage
        {
            get => ProgramLanguageCore;
            set 
            {
                // can't use this
//                 if(value == "C#")
//                 {
//                     throw new ArgumentException($"{nameof(ProgramLanguage)} can not use C#");
//                 }

                this.RaiseAndSetIfChanged(ref ProgramLanguageCore, value);
            }
        }
    }

    internal class LaungageValidationAttribute : ValidationAttribute
    {
        protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
        {
            if(value is string lan)
            {
                if (lan == "C#")
                {
                    return new ValidationResult($"[{validationContext.DisplayName}] can not be C#");
                }
            }

            return ValidationResult.Success;
        }
    }
}
复制代码

      除此之外,也可以手动设置错误,如:

复制代码
        private void OnShowError(object sender, RoutedEventArgs e)
        {
            if(!DataValidationErrors.GetHasErrors(textBox_Errors))
            {
                DataValidationErrors.SetError(textBox_Errors, new ArgumentException("A custom exception error"));
            }
            else
            {
                DataValidationErrors.SetError(textBox_Errors, null);
            }            
        }
复制代码

      这样就可以强制设置错误了。本质上底层也是通过调用这个接口来实现这个能力的。内部其实是设置的是DataValidationErrors.ErrorsProperty:

复制代码
        public static IEnumerable<object> GetErrors(Control control)
        {
            return control.GetValue(ErrorsProperty);
        }
        public static void SetErrors(Control control, IEnumerable<object> errors)
        {
            control.SetValue(ErrorsProperty, errors);
        }
        public static void SetError(Control control, Exception error)
        {
            SetErrors(control, UnpackException(error));
        }
        public static void ClearErrors(Control control)
        {
            SetErrors(control, null);
        }
        public static bool GetHasErrors(Control control)
        {
            return control.GetValue(HasErrorsProperty);
        }
复制代码

      

 

posted @   bodong  阅读(834)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示