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

文章目录

  • 使用ValidationRule实现检测用户输入
    • EmptyValidationRule 非空校验
    • TextBox设置非空校验
    • TextBox设置非空校验并显示校验提示
  • 结语

使用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>

【WPF】使用Behavior以及ValidationRule实现表单校验_第1张图片
【WPF】使用Behavior以及ValidationRule实现表单校验_第2张图片

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

按照上述说明的【需要开启验证错误的通知属性 NotifyOnValidationError,这样可以通过绑定 Validation.Error 事件处理程序获取到Message进行提示】
这边采用的是WPF的行为Behavior。

  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)
    {
        MainViewModel mainModel = null;
        if (AssociatedObject.DataContext is MainViewModel)
        {
            mainModel = this.AssociatedObject.DataContext as MainViewModel;
        }
        if (mainModel == null) return;
        
        //OriginalSource 触发事件的元素
        var element = e.OriginalSource as UIElement;
        if (element == null) return;

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

            mainModel.ErrorMsg = error;
        }
        else if (e.Action == ValidationErrorEventAction.Removed) //ValidationErrorEventAction.Removed  该行为被移除,即代表验证通过
        {
            mainModel.ErrorMsg = 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>
            <Binding
                NotifyOnValidationError="True"
                Path="Age"
                UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <Valid:EmptyValidationRule ValidatesOnTargetUpdated="True" />
                Binding.ValidationRules>
            Binding>
        TextBox.Text>
    TextBox>
    
    <Label
        MinWidth="100"
        VerticalAlignment="Center"
        VerticalContentAlignment="Center"
        Content="{Binding ErrorMsg}"
        FontSize="15"
        Foreground="Red" />
StackPanel>

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

【WPF】使用Behavior以及ValidationRule实现表单校验_第3张图片

效果
【WPF】使用Behavior以及ValidationRule实现表单校验_第4张图片
【WPF】使用Behavior以及ValidationRule实现表单校验_第5张图片

结语

校验异常可以有多种展现形式和方法。
可以在提交按钮时候,判断异常字符串是否为空,不为空弹窗。
可以行为中使用GalaSoft.MvvmLight中的Messenger进行发布订阅(注册消费)。
例如下面这样
当ErrorMsg被赋值时,会触发 Messenger.Default.Send
【WPF】使用Behavior以及ValidationRule实现表单校验_第6张图片
ViewModol中

public string ErrorMsg
{
    get { return _errorMsg; }
    set
    {
        _errorMsg = value;
        if (!string.IsNullOrWhiteSpace(_errorMsg))
        {
            // 发送消息
            Messenger.Default.Send<string, MainView>(_errorMsg);
        }
        RaisePropertyChanged();
    }
}

在页面初始化时注册弹窗事件
【WPF】使用Behavior以及ValidationRule实现表单校验_第7张图片

效果
【WPF】使用Behavior以及ValidationRule实现表单校验_第8张图片

你可能感兴趣的:(wpf)