WPF快速指导5:验证

简介: WPF快速指导5:验证    本文摘要:    1:WPF中的验证处理机制;    2:自定义验证规则;     3:如何显示验证错误信息    4:指定何时进行验证   1:WPF中的验证处理机制    接受用户输入的大多数应用程序都需要具有验证逻辑,以确保用户输入了需要的信息。

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">。就是指定每次输入字符就验证一次。

Creative Commons License本文基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
目录
相关文章
|
.NET C# 开发框架
WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别
WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别 本文摘要: 1:什么是路由事件; 2:中断事件路由; 3:自定义路由事件; 4:为什么需要自定义路由事件; 5:什么是冒泡事件和预览事件(隧道事件); 1:什么是路由事件     WPF中的事件为路由事件,所谓路由事件,MSDN定义如下:     功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。
678 0
|
C# 索引
WPF快速指导3:数据绑定
WPF快速指导3:数据绑定  本文摘要:1:实体类的绑定;2:实体类集合的绑定及DataTemplate;3:自定义的实体类集合,如ObservableDictionary; 4:Path的语法; 1:实体类的绑定          理解WPF数据绑定,首先需要理解接口INotifyCollectionChanged。
851 0
|
C# 数据格式
WPF快速指导4:数据绑定之绑定方向与自定义转换器
WPF快速指导4:数据绑定之绑定方向与自定义转换器    本文摘要:    1:绑定目标与绑定源之间的方向;    2:自定义转换器; 1:绑定目标与绑定源之间的方向    该部分的定义MSDN已经描述的非常清楚了,如下:    您可能希望应用程序使用户可以更改数据并将数据传播回源对象。
730 0
|
C# 前端开发 .NET
WPF快速指导6:触发器
WPF快速指导6:触发器    本文摘要:    1:属性触发器;    2:数据触发器;    3:事件触发器;     Style、ControlTemplate 和 DataTemplate 都有触发器集合。
605 0
|
C# 数据格式 XML
WPF快速指导1:资源
WPF快速指导1:资源    本文摘要:    1:资源应用场景;    2:静态资源和动态资源;    3:Application.Current.Resources和Application.Current.Resources.MergedDictionaries     4:路径 一:资源的应用场景场景1:格式化界面显示元素    所谓格式化界面显示元素,就是使用统一的风格来定义软件的每个界面。
736 0
|
C#
WPF快速指导7:控件和自定义控件
WPF快速指导7:控件和自定义控件 本文摘要: 1:控件和自定义控件的概念; 2:更改控件的外观; 3:自定义控件的设计原则;   1:控件和自定义控件的概念     Windows Presentation Foundation (WPF) 附带了许多几乎在所有 Windows 应用程序中都会使用的常见 UI 组件,如 Button、Label、TextBox、Menu 和 ListBox。
1233 0
|
C# 开发工具
WPF快速指导8:WPF基元素类
WPF快速指导8:WPF基元素类 本文摘要: 1:什么是基元素类; 2:基元素类的使用; 3:其它重要基类   1:什么是基元素类      WPF中的大部分类都是从 SDK 文档中通常称为基元素类的四个类派生而来。
1384 0
|
C#
WPF快速指导9:WPF中的属性(依赖项属性)
WPF快速指导9:WPF中的属性(依赖项属性) 本文摘要: 1:什么是依赖项属性; 2:实现依赖项属性;   1:什么是依赖项属性     Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR) 属性的功能。
956 0
|
API C#
WPF快速指导11:输入和命令
WPF快速指导11:输入和命令 本文摘要: 1:输入的种类; 2:命令       1:输入的种类     可在基元素类上找到公开的主输入 API:UIElement、ContentElement、FrameworkElement 和 FrameworkContentElement。
1007 0
|
16天前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库