【WPF】使用Behavior以及ValidationRule实现表单校验

本文详细介绍了如何在WPF中使用ValidationRule实现TextBox的非空校验,并展示了如何通过NotifyOnValidationError和Validation.Error事件来显示校验提示。同时介绍了IValidationExceptionHandler接口和ValidationExceptionBehavior的行为实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用ValidationRule实现检测用户输入

EmptyValidationRule是TextBox内容是否为空校验,TextBox的Binding属性设置ValidationRule后,TextBox将自带校验红框效果。但是默认是没有报错提示的。需要开启验证错误的通知属性 NotifyOnValidationError,这样可以通过绑定 Validation.Error 事件处理程序获取到Message进行提示

EmptyValidationRule 非空校验

public class EmptyValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string str = value as string;
        if (string.IsNullOrWhiteSpace(str))
        {
            return new ValidationResult(false, "不能为空,输入有效值");
        }
        return ValidationResult.ValidResult;
    }
}

TextBox设置非空校验

UpdateSourceTrigger="PropertyChanged" 设置每次输入都触发双向绑定,Binding.ValidationRules 设置校验逻辑
ValidatesOnTargetUpdated="True" 设置 首次加载就校验(默认启动程序的时候不开启校验,当你第一次输入才校验)

<StackPanel
    Grid.Row="1"
    HorizontalAlignment="Center"
    Orientation="Horizontal">
    <TextBlock VerticalAlignment="Center" Text="年龄:" />
    <TextBox
        Width="200"
        Height="30"
        Margin="10,0"
        VerticalAlignment="Center"
        VerticalContentAlignment="Center">
        <TextBox.Text>
            <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <Valid:EmptyValidationRule ValidatesOnTargetUpdated="True" />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
</StackPanel>

在这里插入图片描述
在这里插入图片描述

TextBox设置非空校验并显示校验提示

按照上述说明的【需要开启验证错误的通知属性 NotifyOnValidationError,这样可以通过绑定 Validation.Error 事件处理程序获取到Message进行提示】
这边采用的是WPF的行为Behavior。
IValidationExceptionHandler,输入校验接口,需要进行校验的页面的ViewModel需要继承并实现他的两个属性IsValid 以及
Message

/// <summary>
/// 输入校验接口
/// </summary>
public interface IValidationExceptionHandler
{
    /// <summary>
    /// 是否有校验异常
    /// </summary>
    bool IsValid { get; set; }

    /// <summary>
    /// 异常提示
    /// </summary>
    string Message { get; set; }
}
  1. 首先先定义一个行为 ValidationExceptionBehavior
public class ValidationExceptionBehavior : Behavior<FrameworkElement>
{

    // 实现你的行为逻辑
    protected override void OnAttached()
    {
        // 在此处理附加逻辑
        // AssociatedObject 就是 行为的对象 FrameworkElement
        AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError));
    }

    protected override void OnDetaching()
    {
        // 在此处理分离逻辑
        //移除 Validation.Error 事件监听
        this.AssociatedObject.RemoveHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError));
    }

    private void OnValidationError(object sender, ValidationErrorEventArgs e)
    {
        IValidationExceptionHandler validationException = null;
        if (AssociatedObject.DataContext is IValidationExceptionHandler)
        {
            validationException = this.AssociatedObject.DataContext as IValidationExceptionHandler;
        }
        if (validationException == null) return;
        
        //OriginalSource 触发事件的元素
        var element = e.OriginalSource as UIElement;
        if (element == null) return;

        //ValidationErrorEventAction.Added  表示新产生的行为
        if (e.Action == ValidationErrorEventAction.Added)
        {
            // EmptyValidationRule返回的结果字符串
            validationException.IsValid = true;
            string error = e.Error.ErrorContent.ToString();

            validationException.Message = error;
        }
        else if (e.Action == ValidationErrorEventAction.Removed) //ValidationErrorEventAction.Removed  该行为被移除,即代表验证通过
        {
            validationException.IsValid = false;
            validationException.Message = string.Empty;
        }
    }

    
}

  1. TextBox的Binding属性中的NotifyOnValidationError="True",开启验证错误的通知属性,产生 Validation.Error 事件。
<StackPanel
    Grid.Row="1"
    HorizontalAlignment="Center"
    Orientation="Horizontal">
    <TextBlock VerticalAlignment="Center" Text="年龄:" />
    <TextBox
        Width="200"
        Height="30"
        Margin="10,0"
        VerticalAlignment="Center"
        VerticalContentAlignment="Center">
        <TextBox.Text>
        <!--  开启验证错误的通知属性 NotifyOnValidationError=“True” 。这样就可以产生 Validation.Error 事件  -->
            <Binding
                NotifyOnValidationError="True"
                Path="Age"
                UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                <!--  ValidatesOnTargetUpdated="True" 首次加载就校验  -->
                    <Valid:EmptyValidationRule ValidatesOnTargetUpdated="True" />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <!--  显示校验异常内容  -->
    <Label
        MinWidth="100"
        VerticalAlignment="Center"
        VerticalContentAlignment="Center"
        Content="{Binding Message}"
        FontSize="15"
        Foreground="Red" />
</StackPanel>

  1. 绑定行为
    引入命名空间 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    绑定行为
<i:Interaction.Behaviors>
    <Valid:ValidationExceptionBehavior />
</i:Interaction.Behaviors>

在这里插入图片描述

效果
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

结语

校验异常可以有多种展现形式和方法。
可以在提交按钮时候,判断异常字符串是否为空,不为空弹窗。
可以行为中使用GalaSoft.MvvmLight中的Messenger进行发布订阅(注册消费)。
例如下面这样
当Message被赋值时,会触发 Messenger.Default.Send
在这里插入图片描述

ViewModol中

private string _message;

/// <summary>
/// 实现 IValidationExceptionHandler的成员Message
/// </summary>
public string Message
{
    get { return _message; }
    set
    {
        _message = value;
        if (!string.IsNullOrWhiteSpace(_message))
        {
            // 发送消息
            Messenger.Default.Send<string, MainView>(_message);
        }

        RaisePropertyChanged();
    }
}

在页面初始化时注册弹窗事件
在这里插入图片描述

效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值