• WPF中的数据验证


    数据验证

    WPF的Binding使得数据能够在数据源和目标之间流通,在数据流通的中间,便能够对数据做一些处理。
    数据转换数据验证便是在数据从源到目标 or 从目标到源 的时候对数据的验证和转换。
    Binding

    ValidationRule 验证规则

    WPF中提供了一个抽象类ValidationRule,我们自定义的验证规则都需要继承它,然后实现它的抽象
    方法Validate,该方法需要返回一个ValidationResult对象来表示验证结果。举个例子,一个验证数字
    的规则(输入的只能是数字)

    public class NumberValidationRule : ValidationRule
        {
            public override ValidationResult Validate(object value, CultureInfo cultureInfo)
            {
                if (Regex.IsMatch(value.ToString(), "^[0-9]+$"))
                {
                    return new ValidationResult(true, null);
                }
                else
                {
                    return new ValidationResult(false, "请输入数字");
                }
            }
        }

    其中ValidationRule的两个属性

    • ValidatesOnTargetUpdated

      该属性可以确定验证的方向,如果设置为false,那么只验证从目标到源的方向,如果为True,
      那么同时也会验证从源到目标的方向

    • ValidationStep
      该属性确定了验证的时机,它是一个枚举值
      1 CommittedValue,该值提交到数据源后,运行ValidationRule,即不管验证是否能通过,属性都会被更新
      2 ConvertedProposedValue,在进行了转换之后,运行ValidationRule,如果有数据转换,那么先转换再验证
      3 RawProposedValue,在任何转换发生之前,运行ValidationRule
      4 UpdatedValue,在更新了源后,运行ValidationRule,即属性值被更改之后,就会去验证,注意需要
      ValidatesOnTargetUpdated设置为True

    还需要注意的是Binding对验证结果的处理,NotifyOnValidationError设置为True,即当发生验证
    错误时,错误信息会从目标沿着可视树往上冒泡,直到该冒泡事件被侦听到并被处理。

       <TextBox Grid.Row="1">
                <TextBox.Text>
                    <Binding Path="Number" UpdateSourceTrigger="PropertyChanged" Converter="{StaticResource Converter}" NotifyOnValidationError="True">
                        <Binding.ValidationRules>
                            <validationRules:NumberValidationRule ValidatesOnTargetUpdated="True" ValidationStep="CommittedValue"></validationRules:NumberValidationRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

    当出现验证错误时,TextBox就会有一个红色的框,这是默认的错误模板样式,我们如何定义一个错误模板(ErrorTemplate)呢

    错误模板 ErrorTemplate

       <ControlTemplate x:Key="ErrorTemplate">
                <StackPanel Orientation="Horizontal">
                    <AdornedElementPlaceholder x:Name="Placeholder"></AdornedElementPlaceholder>
                    <TextBlock Foreground="Red" Text="{Binding ElementName=Placeholder,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" FontSize="20" x:Name="txt"></TextBlock>
                </StackPanel>
            </ControlTemplate>
      <TextBox Grid.Row="1" Height="30" Width="100" Validation.ErrorTemplate="{StaticResource ErrorTemplate}">

    AdornedElementPlaceholder表示一个占位符,这里表示具体的控件即TextBox,这里表示错误模板的布局是
    如果有验证错误,那么在TextBox的后边会有一个TextBlock文本,文本的内容显示的是验证错误的信息。

    Validation

    这里涉及到了一个类Validation,它是一个静态类,它的使用大多以附加属性出现。它的主要功能是
    1 设置ErrorTemplate
    2 判断是否有错误(HasError),以及获取错误列表(Errors)
    3 侦听验证错误事件

    前两点前面都有提到,现在来看下 侦听验证错误冒泡事件

    <Grid Grid.Row="1" Validation.Error="Validation_OnError">
                <TextBox Height="30" Width="100" Validation.ErrorTemplate="{StaticResource ErrorTemplate}">
                    <TextBox.Text>
                        <Binding Path="Number" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
                            <Binding.ValidationRules>
                                <validationRules:NumberValidationRule></validationRules:NumberValidationRule>
                            </Binding.ValidationRules>
                        </Binding>
                    </TextBox.Text>
                </TextBox>
            </Grid>
    
     private void Validation_OnError(object sender, ValidationErrorEventArgs e)
        {
    
            if (e.Action == ValidationErrorEventAction.Added)
            {
                //todo:新的验证错误
                _errorMessage = e.Error.ErrorContent.ToString();
            }
            else
            {
                //todo:清除原有错误
                _errorMessage = string.Empty;
            }
        }

    这里需要注意的其实就是ValidationErrorEventAction这个枚举值,因为产生新的验证错误,和清除
    原来的验证错误都会触发这个事件,所以需要区分开来对待。
    至此,WPF中的数据验证差不多了。

  • 相关阅读:
    电容在电路中的作用
    C语言中的弱符号(weak)用法及实例
    一种高灵敏度自带DSP降噪算法的音频采集解决方案
    高灵敏度自带DSP降噪算法的audio codec解决方案
    git clone error: RPC failed; curl 18 transfer closed with outstanding read data remaining
    stm32f103中freertos的tasks基本使用案例及备忘
    移植freertos到stm32 f103 的基本流程和总结
    stm32_f103使用gcc编译的环境下printf打印函数的实现
    C语言中指针和取地址符&的关系
    STM32中ARM系列编译工具链的编译宏选择(__CC_ARM、__ICCARM__、__GNUC__、__TASKING__)
  • 原文地址:https://www.cnblogs.com/sjqq/p/8456906.html
Copyright © 2020-2023  润新知