彩票走势图

WPF绑定后如何验证用户输入合法性

转帖|其它|编辑:郝浩|2011-03-31 13:57:12.000|阅读 1711 次

概述:在我们绑定完数据后,在用户输入数据后,还需要进行用户输入合法性验证,比如需要判断 必填项,email地址输入格式,日期格式是否正确等。wpf为我们提供了一种验证用户合法行的方式。依赖于绑定。在将实体数据绑定到视图后,如果用户输入的视图改变,则同时通知实体的属性值改变。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  在我们绑定完数据后,在用户输入数据后,还需要进行用户输入合法性验证,比如需要判断 必填项,email地址输入格式,日期格式是否正确等。

  wpf为我们提供了一种验证用户合法行的方式。依赖于绑定。在将实体数据绑定到视图后,如果用户输入的视图改变,则同时通知实体的属性值改变。先看代码:

  1. 构建一个要绑定到界面的实体。该实体实现了IDataErrorInfo接口,在接口里写了验证规则。

//实体 实现 IDataErrorInfo接口,并在 this[]索引器里定制自己的验证规则

using System.ComponentModel;
namespace TextVerify
{
     partial class eva:IDataErrorInfo
     {

         string _err;
         public string Error
         {
             get { return _err; }
         }

         //定制验证规则
         public string this[string columnName]
         {
             get
             {
                 string err =  "";
                 switch (columnName)
                 {
                     case  "Name":
                         if (string.IsNullOrEmpty(this.Name))
                         {
                             err =  "名称不能为空";
                         }
                         else
                         {
                             if (this.Name.Length  > 8)
                             {
                                 err =  "名称太长了,不能大于8个字符";
                             }
                         }
                         break;
                     case  "Value":

                         if (this.value  < 0 || this.value > 200)
                         {
                             err =  "数字不合法";
                         }
                         break;
                 }
                 _err = err;
                 return _err;
             }
         }


     }
}

  2.页面:

<Window x:Class="TextVerify.MainWindow"
         xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x= "//schemas.microsoft.com/winfx/2006/xaml"
         Title= "MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
     <Grid Name="eee">
  <TextBox Height="23" HorizontalAlignment="Left" 

Margin="152,73,0,0" Name="name" 
Text="{Binding Path=Name, Mode=TwoWay,UpdateSourceTrigger=

'PropertyChanged',ValidatesOnDataErrors=True}"
  VerticalAlignment= "Top" Width="120" >
           <Validation.ErrorTemplate>
             <ControlTemplate>
                 <!-- ControlTemplate要求只能有一个子级,所以加个容器控件DockPanel -->
                 <DockPanel>
                     <!-- AdornedElementPlaceholder就是要验证的控件本身,本例里是个TextBox -->
                     <AdornedElementPlaceholder />
                     <TextBlock Foreground="Red" FontSize="20" Text="*" />
                 </DockPanel>
             </ControlTemplate>
             </Validation.ErrorTemplate>
         </TextBox>

        <Button Content=";保  存" Height="23" 

HorizontalAlignment="Left" Margin="152,114,0,0" 

Name="button1"
  VerticalAlignment= "Top" Width="75" Click="button1_Click" />
     </Grid>

</Window>

  32

  页面的后台代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TextVerify
{
     ///  <summary>
     /// MainWindow.xaml 的交互逻辑
     ///  </summary>
     public partial class MainWindow : Window
     {
     //    EvaDAO ed = new EvaDAO();
     //    eva er = new eva();
         public MainWindow(){}
         //public MainWindow(eva er)
         //{
         //    InitializeComponent();
         //    //eee.DataContext = er;
         //}
         ///  <summary>
         /// 保存
         ///  </summary>
         ///  <param name="sender"></param>
         ///  <param name="e"></param>
         private void button1_Click(object sender, RoutedEventArgs e)
         {
             //if(name.Text== "" || name.Text==""){
             //    return;
             //}
             //er.Name = name.Text;
             //er.value = 222222;
             ////MessageBox.Show(er+ "===");
             //ed.Save(er);
         }

         private void Window_Loaded(object sender, RoutedEventArgs e)
         {
             eee.DataContext = GetEvaFromDatabase();
         }
         private eva GetEvaFromDatabase()
          {
              //从数据库获得数据对象  <演示>
              return new eva() { Name =  "sa", value = 123 };
          }

     }
}

  按F5运行后,尝试输入写不合法数据。可以看到Textbox的边框变成红色。这是一种默认的提示错误的风格方式,我们还可以对这个提示风格进行自定义。

  注意Binding的下面两个属性:

  ValidatesOnDataErrors 获取或设置一个值,该值指示是否包含 DataErrorValidationRule。

  ValidationRules 获取用于检查用户输入有效性的规则集合。

  也就是说当我们设置了 Binding的ValidatesOnDataErrors="True" 时。WPF框架在构造Binding对象时,会自动的添加一个默认的DataErrorValidationRule到ValidationRules  属性值(验证规则列表)内。或者我们直接在ValidationRules 里添加我们需要的规则,比如下面是添加了两个规则:

<Binding.ValidationRules>
                        <DataErrorValidationRule />
                        <ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>

  这样的写法很有意思,貌似IOC的方式配置文件,比如spring.Net的配置文件,这样的声明ValidationRules的包含的规则。当WPF框架创建对象时自动的完成规则操作,并判断ValidationRules内的规则数量,如果多于0个,就遍历所有的规则集合,如果集合中包含了DataErrorValidationRule 并且实体类显示了IDataErrorInfo

  接口,就调用 实体内包含的 验证规则。

  ExceptionValidationRule 类是一个内置的规则,它检查在绑定源属性更新过程中引发的异常。这里验证了Age的用户输入不可为空,当为空时,转型成int(Age是int类型)时就会出错。

  通过创建一个从 ValidationRule 派生的类,可以创建自定义规则。下面我尝试自定义验证规则。

  MSDN里对ValidateionRule的描述如下:

  在使用 WPF 数据绑定模型时,可将 ValidationRules 与绑定对象关联。若要创建自定义规则,请创建此类的子类并实现 Validate 方法。也可选择使用内置的 ExceptionValidationRule(该类捕获在源更新期间引发的异常)或 DataErrorValidationRule(该类检查源对象的 IDataErrorInfo 实现所引发的错误)。

  绑定引擎在每次将输入值(即绑定目标属性值)传给绑定源属性时将检查与绑定关联的每一个 ValidationRule。

  页面xaml代码如下,而后置代码不变。

  下面我们看看如何更改在验证失败时的提示风格

<Window x:Class="TextVerify.MainWindow"
         xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x= "//schemas.microsoft.com/winfx/2006/xaml"
  Title= "MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
     <Grid Name="eee">
  <;TextBox Height="23" HorizontalAlignment="Left" 

Margin="152,73,0,0" Name="name" 
Text=&quot;{Binding Path=Name, Mode=TwoWay,UpdateSourceTrigger=

'PropertyChanged',ValidatesOnDataErrors=True}"
  VerticalAlignment= "Top" Width="120" >
           <Validation.ErrorTemplate>
             <ControlTemplate>
                 <!-- ControlTemplate要求只能有一个子级,所以加个容器控件DockPanel -->
                 <DockPanel>
                     <!-- AdornedElementPlaceholder就是要验证的控件本身,本例里是个TextBox -->
                     <AdornedElementPlaceholder />
                     <TextBlock Foreground="Red" FontSize="20" Text="*" />
                 </DockPanel>
             </ControlTemplate>
             </Validation.ErrorTemplate>
         </TextBox>

         <Button Content="保   存" Height="23" HorizontalAlignment="Left" Margin="152,114,0,0"
  Name= "button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
     </Grid>
     <Window.Resources>
         <Style TargetType="TextBox">
             <Style.Triggers> 
                 <Trigger Property="Validation.HasError" Value="True"> 
                     <Setter Property="Background" Value="#DDD" />
                     <Setter Property="Foreground" Value="Red" />
                     <Setter Property="ToolTip"  
   Value= "{Binding RelativeSource={RelativeSource Self},

Path=(Validation.Errors)[0].ErrorContent}"/>
                 </Trigger>
             </Style.Triggers>
         </Style>
     </Window.Resources>
</Window>

  我们注意到Textbox.Validation属性的ErrorTemplate是发生错误时使用的模板,我们重新new了一个ControlTemplate来代替这个模板。在这个模板里我们定义了一个DockPanel作为容器控件,使用 占位标记AdornedElementPlaceholder 标记了TextBox的位置,并在它后面添加两个 字符"*"号。这可能有点难以理解。换个说法是,每个TextBox都有个Validation属性,Validation包含了一些和验证相关的像,包含有个当验证失败时的显示模板。而我们重新定义了个显示模板。这个模板里有个占位符,占位符表示TextBox本身,我们在这个模板的占位符后面添加一些字符 红色的"*" 号。那么当TextBox在执行时,如果失败,就会把 错误模板 显示出来,并在 占位符位置 显示自己。

  我们换个另外的方式来改变视图效果,使用style 方式。

  在窗体资源里添加一个style,style这个东西呢,类似web开发中的css。他有个属性TargetType 指示了这个样式的作用域。本例中指示了 所有的TextBox,style的强大之处还有个Triggers就是触发器。本例中触发器指向一个属性Validation.HasError属性,当这属性的值为"True"时,触发Trigger包含的样式。当不等于"True"时,自动改回原来的样式。很强大吧。Setter元素提供了设置目标对象属性的方法,我们直接更改了Textbox.ToolTop属性,那么当鼠标移动到控件上时,就会显示发生错误的原因。

 1<Window.Resources>
  2         <Style TargetType="TextBox">
  3              <Style.Triggers>
  4                  <Trigger Property="Validation.HasError" Value="True">
  5                      <Setter Property="Background" Value="#DDD" />
  6                      <Setter Property="Foreground" Value="Red" />
  7                      <Setter Property="ToolTip"  
  8  &nbsp;   Value= "{Binding RelativeSource={RelativeSource Self},

Path=(Validation.Errors)[0].ErrorContent}"/>
  9                  </Trigger>
10             </Style.Triggers>
11         </Style>
12 &nbsp;   </Window.Resources>

  这句

  <Setter Property="ToolTip"  
      ;      Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"/>

  完成了获得关联数据源,并绑定错误提示的操作。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:网易博客

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP