zoukankan      html  css  js  c++  java
  • WPF快速指导5:验证

    WPF快速指导5:验证
        本文摘要:
        1:WPF中的验证处理机制;
        2:自定义验证规则;
        3:如何显示验证错误信息
        4:指定何时进行验证

    1:WPF中的验证处理机制
        接受用户输入的大多数应用程序都需要具有验证逻辑,以确保用户输入了需要的信息。验证检查可以基于类型、范围、格式或其他应用程序特定的要求。本节讨论了数据验证在 WPF 中的工作方式。

        先来看一个简单的例子

        <Window.Resources>
            <local:Person x:Key="luminji" Name="luminji" Age="3"></local:Person>
        </Window.Resources>
        <StackPanel DataContext="{StaticResource luminji}" >
            <TextBox x:Name="textBoxAge">
                <TextBox.Text>
                    <Binding Path="Age" NotifyOnValidationError="True">
                        <Binding.ValidationRules>
                            <ExceptionValidationRule></ExceptionValidationRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
            <Button>Button</Button>
        </StackPanel>

         后台:

        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                Validation.AddErrorHandler(this.textBoxAge, delegate(object sender, ValidationErrorEventArgs e)
                {
                    MessageBox.Show(e.Error.ErrorContent.ToString());
                });
            }
        }
    
        class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        WPF中的验证处理机制是:当验证结果出现非法数据时,就会产生一个包含错误信息的ValidationError对象供界面进行显示。在使用了ExceptionValidationRule的情况下,这个错误对象会包含验证规则所捕获到的Exception对象的Message属性。当然,为了,访问到这个异常,我们需要为页面的Validation对象添加附件事件,即上文中Validation.AddErrorHandler(……)。注意,为了能捕获这个事件,还需要将数据绑定中的NotifyOnValidationError设置为True。
        把这段代码运行起来,如果你在文本框中输入的不是数字,则会弹出ExceptionValidationRule中默认的“输入字符串的格式不正确”。但是显然,这种系统默认提供给我们的提示信息不能满足我们的要求。如果要对错误进行更多的自定义处理,首先就要自定义验证规则。


    2:自定义验证规则

        自定义验证规则需要继承抽象类ValidationRule,并重写Validate方法。然后在XAML中的ExceptionValidationRule换成自定义的验证规则类就行。
        前台中相应替换的内容:

                <TextBox.Text>
                    <Binding Path="Age" NotifyOnValidationError="True">
                        <Binding.ValidationRules>
                            <local:AgeRule></local:AgeRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
        后台的自定义验证类:
        class AgeRule: ValidationRule
        {
    
            public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
            {
                int number;
                if (!int.TryParse((string)value, out number))
                {
                    return new ValidationResult(false, "输入的内容必须为数字!");
                }
                else if( number > 100 || number < 0)
                {
                    return new ValidationResult(false, "输入的年龄超过范围");
                }
                else
                {
                    //return new ValidationResult(true, null);
                    return ValidationResult.ValidResult;
                }
            }
        }

         我们注意到,上文中的100和0是硬编码,还有一种虽然是前台硬编码,但是看上去要舒服很多,见下文:
         前台中相应替换的内容:

                <TextBox.Text>
                    <Binding Path="Age" NotifyOnValidationError="True">
                        <Binding.ValidationRules>
                            <local:AgeRule Max="100" Min="0"></local:AgeRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>

         后台中相应变化的内容:

        class AgeRule: ValidationRule
        {
            public int Min { get; set; }
            public int Max { get; set; }
            public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
            {
                int number;
                if (!int.TryParse((string)value, out number))
                {
                    return new ValidationResult(false, "输入的内容必须为数字!");
                }
                else if( number > Max || number < Min)
                {
                    return new ValidationResult(false, "输入的年龄超过范围");
                }
                else
                {
                    //return new ValidationResult(true, null);
                    return ValidationResult.ValidResult;
                }
            }
        }

    3:如何显示验证错误信息
        在上文中,我们通过MessageBox来显示验证的错误信息。看上去有点业余,即用户友好度不够,更好的处理方法是在UI上指定一个固定的区域进行显示。指定固定区域进行显示有三种方法。
        第一种,是在Validation.AddErrorHandler为某个区域赋值错误信息。如下文代码中的textBlockErrorMessage0。
        第二种,是为区域绑定错误信息,如下文代码中的textBlockErrorMessage1。
        第三种,是为Validation.HasError设定触发器,指定Validation.ErrorTemplate来动态显示错误信息。
        提倡第三种做法。
        前台代码:

        <Window.Resources>
            <local:Person x:Key="luminji" Name="luminji" Age="3"></local:Person>
            <Style TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="Validation.ErrorTemplate">
                            <Setter.Value>
                                <ControlTemplate>
                                    <DockPanel LastChildFill="True">
                                        <TextBlock DockPanel.Dock="Right" Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                        </TextBlock>
                                        <Border BorderBrush="Red" BorderThickness="1">
                                            <AdornedElementPlaceholder Name="MyAdorner"/>
                                        </Border>
                                    </DockPanel>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <StackPanel DataContext="{StaticResource luminji}" >
            <TextBox x:Name="textBoxAge" Width="100">
                <TextBox.Text>
                    <Binding Path="Age" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:AgeRule Max="100" Min="0"></local:AgeRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
            <TextBlock x:Name="textBlockErrorMessage0"/>
            <TextBlock x:Name="textBlockErrorMessage1" Text="{Binding ElementName=textBoxAge, Path=(Validation.Errors)[0].ErrorContent}" />
            <Button>Button</Button>
        </StackPanel>

          后台代码代码因为和上文的后台代码没有太多区别,故略。
          值得注意的是,前台代码的触发器中,<TextBlock DockPanel.Dock="Right" Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">,AdornedElement这个属性不能少。AdornedElement表示的是当前装饰器所在的UIElement。


    4:指定何时进行验证
        上文的例子中,我们都是在文本框失去焦点的时候看到验证的错误信息的。我们还可以指定这个验证的时机,就是为文本框的绑定设置UpdateSourceTrigger。如:<Binding Path="Age" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">。就是指定每次输入字符就验证一次。

  • 相关阅读:
    MySQL-数据表操作
    MySQL基础命令
    Navicat 15激活
    禅道-启动失败问题整理
    python-开头的注释作用及区别
    SpringBoot、SpringCloud版本中GA/PRE/SNAPSHOT的详解
    mybatis的一些重要配置
    简历对应的知识点
    idea的破解
    SFTP和FTP的区别
  • 原文地址:https://www.cnblogs.com/luminji/p/1944930.html
Copyright © 2011-2022 走看看