热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WPFBindingValidation数据验证

表单的数据验证往往枯燥无味,又不可避免.
在一个如下表单只有两个输入框,和确定按钮的情况下,正常我们需要做哪些工作呢?
WPF Binding Validation 数据验证

 

1. 如果年龄输入框输入了非数字的字符串,输入框失去焦点后,后面错误消息应当能立即提示出来

2.错误的提示的内容如果变化,你可能需要修改整个UI设计.(如显示在输入框下方)

3.点击OK按钮,需要遍历Window所有输入框,如果有输入数据验证不符合,需要提示错误,并将对应的控件获取焦点.

这很容易么?当这个输入框再多一些呢?

下面的Demo,看在WPF如何轻松处理这些:

WPF Binding Validation 数据验证

Window里,textBox1,textBox2,textBox3 绑定的数据为:

class MyDataSource { private int _age; private int _age2; private int _age3; public MyDataSource() { Age = 0; Age2 = 0; } public int Age { get { return _age; } set { _age = value; } } public int Age2 { get { return _age2; } set { _age2 = value; } } public int Age3 { get { return _age3; } set { _age3 = value; } } }
  • 使用自定义验证规则
<TextBox Name="textBox1" Width="50" FontSize="15"
         Validation.ErrorTemplate="{StaticResource validationTemplate}"
         Style="{StaticResource textBoxInError}"
         Grid.Row="1" Grid.Column="1" Margin="2">
  <TextBox.Text>
    <Binding Path="Age" Source="{StaticResource ods}"
             UpdateSourceTrigger="PropertyChanged" >
      <Binding.ValidationRules>
        <c:AgeRangeRule Min="21" Max="130"/>
      Binding.ValidationRules>
    Binding>
  TextBox.Text>
TextBox>
 

textBox1 绑定了Age ,并且使用的验证的规则为 AgeRangeRule ,规则中指定了最小值和最大值,当PropertyChanged时验证规则将触发,也就是该控件失去焦点之时. 提示的信息样式定义在ErrorTemplate里,让我们再来看一看ErrroTemplate的内容:

      <ControlTemplate x:Key="validationTemplate">
        <DockPanel>
          <TextBlock Foreground="Red" FontSize="20">!TextBlock>
          <AdornedElementPlaceholder/>
        DockPanel>
      ControlTemplate>


AdornedElementPlaceholder 才是这里的点睛之处,此处放置了待验证的控件,而整个ErrorTemplate正是使用神奇的Adoner实现了错误的提示的位置和原排版布局的无关性. 验证规则和整个代码完全解耦:

class AgeRangeRule : ValidationRule { private int _min; private int _max; public AgeRangeRule() { } public int Min { get { return _min; } set { _min = value; } } public int Max { get { return _max; } set { _max = value; } } public override ValidationResult Validate(object value, CultureInfo cultureInfo) { int age = 0; try { if (((string)value).Length > 0) age = Int32.Parse((String)value); } catch (Exception e) { return new ValidationResult(false, "Illegal characters or " + e.Message); } if ((age Max)) { return new ValidationResult(false, "Please enter an age in the range: " + Min + " - " + Max + "."); } else { return new ValidationResult(true, null); } } }

验证规则验证失败时候抛出的异常显示在Tip里.

     <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
        <Style.Triggers>
          <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip"
              Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                              Path=(Validation.Errors)[0].ErrorContent}"/>
          Trigger>
        Style.Triggers>
      Style>
  • 使用ExceptionValidationRule


另一种方法,不自定义Rule,如:

 <TextBox Name="textBox3" Width="50" FontSize="15"
             Grid.Row="5" Grid.Column="1" Margin="2"
             Validation.ErrorTemplate="{StaticResource validationTemplate}"
             Style="{StaticResource textBoxInError}">
      <TextBox.Text>
        <Binding Path="Age3" Source="{StaticResource ods}"
                 UpdateSourceTrigger="PropertyChanged">
          <Binding.ValidationRules>
            <ExceptionValidationRule/>
          Binding.ValidationRules>
        Binding>
      TextBox.Text>
    TextBox>

在后台代码中:

 
        BindingExpression myBindingExpression = textBox3.GetBindingExpression(TextBox.TextProperty);
            Binding myBinding = myBindingExpression.ParentBinding;
            myBinding.UpdateSourceExceptiOnFilter= new UpdateSourceExceptionFilterCallback(ReturnExceptionHandler);
            myBindingExpression.UpdateSource();
 

因为Age3Int类型,在textBox3 输入非int类型,将会引发异常,此时使用Rule的正是系统的ExceptionValidationRule,同样错误信息的模块不变.

  • 验证所有控件
    // Validate all dependency objects in a window bool IsValid(DependencyObject node) { // Check if dependency object was passed if (node != null) { // Check if dependency object is valid. // NOTE: Validation.GetHasError works for controls that have validation rules attached bool isValid = !Validation.GetHasError(node); if (!isValid) { // If the dependency object is invalid, and it can receive the focus, // set the focus if (node is IInputElement) Keyboard.Focus((IInputElement)node); return false; } } // If this dependency object is valid, check all child dependency objects foreach (object subnode in LogicalTreeHelper.GetChildren(node)) { if (subnode is DependencyObject) { // If a child dependency object is invalid, return false immediately, // otherwise keep checking if (IsValid((DependencyObject)subnode) == false) return false; } } // All dependency objects are valid return true; }

    在点击确定可使用该方法再次验证,在数据不合法的情况下,使用户无法提交

代码: 下载


推荐阅读
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 本文详细介绍了如何在Unity中实现一个简单的广告牌着色器,帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 重要知识点有:函数参数默许值、盈余参数、扩大运算符、new.target属性、块级函数、箭头函数以及尾挪用优化《深切明白ES6》笔记目次函数的默许参数在ES5中,我们给函数传参数, ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • com.hazelcast.config.MapConfig.isStatisticsEnabled()方法的使用及代码示例 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 本文详细介绍了如何在 Django 项目中使用 Admin 管理后台,包括创建超级用户、启动项目、管理数据模型和修改用户密码等步骤。 ... [详细]
author-avatar
只属于我一个人的秘密
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有