WPF 数据验证

摘要:
在软件UI界面中输入数据时,为了确保数据的正确性、有效性和标准化,在许多情况下必须验证数据的有效性。例如,如果输入了一个人的信息,我们需要验证该人的姓名是否为空字符串,年龄是否为有效数字,性别是男性还是女性,等等。在WPF开发中,数据验证和数据绑定结合在一起,非常优雅。我们可以让数据模型实现IDataErrorInfo接口来实现每个属性的验证逻辑。然后在Xaml中提供控件的ErrorTemplate模板,以获得良好的验证效果。

  在软件UI界面录入数据时候,为了保证数据的正确、有效、规范性,很多情况下都要验证数据的有效性。比如录入某个人的信息,那么我们就需要对这个人的姓名验证是否为空字符串,年龄是否为有效数字,性别是否为男或女等等。

  在WPF开发中,数据的验证和数据绑定结合在一起,实现起来很优雅。我们可以让数据Model(模型)实现IDataErrorInfo接口来实现每个属性的验证逻辑。或者自定义一个继承自ValidationRule的类来实现验证逻辑。然后在Xaml中提供控件的ErrorTemplate模板,就可以得到很好的验证效果。下面提供一个样例代码:

  

WPF 数据验证第1张WPF 数据验证第2张后台数据
 1  public class Person : IDataErrorInfo
 2      {
 3          public string Name { get; set; }
 4  
 5          public int Age { get; set; }
 6  
 7          public string Sex { get; set; }
 8  
 9          public string Error
10          {
11              get { return "输入字符串无效"; }
12          }
13  
14          public string this[string columnName]
15          {
16              get
17              {
18                  string msg = string.Empty;
19                  switch (columnName)
20                  {
21                      case "Name":
22                          {
23                              if (string.IsNullOrEmpty(this.Name.Trim()))
24                              {
25                                  msg = "*请完善姓名内容";
26                              }
27                              break;
28                          }
29                      case "Age":
30                          {
31                              if (this.Age < 0 || this.Age > 120)
32                              {
33                                  msg = "*年龄范围为{0-120}之间";
34                              }
35                              break;
36                          }
37                      case "Sex":
38                          {
39                              if (string.IsNullOrEmpty(this.Sex.Trim()) ||
40                                 !(this.Sex.Trim() == "Boy" || this.Sex.Trim() == "Girl"))
41                              {
42                                  msg = "*你确定你既不是Boy也不是Girl吗?";
43                              }
44                              break;
45                          }
46                  }
47                  return msg;
48              }
49          }
50      }
51  
52      public class AgeValidate : ValidationRule
53      {
54          private int minAge;
55          public int MinAge
56          {
57              get { return minAge; }
58              set { minAge = value; }
59          }
60  
61          private int maxAge;
62          public int MaxAge
63          {
64              get { return maxAge; }
65              set { maxAge = value; }
66          }
67  
68          public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
69          {
70              int age;
71              string msg = string.Format("请输入大于{0}小于{1}的数字", minAge, maxAge);
72              if (int.TryParse(value.ToString(), out age))
73              {
74                  if (age < minAge || age > maxAge)
75                      return new ValidationResult(false, msg);
76                  else
77                      return new ValidationResult(true, null);
78              }
79              else
80              {
81                  return new ValidationResult(false, "请输入数字");
82              }
83          }
84      }
85 
86   public MainWindow()
87          {
88              InitializeComponent();
89  
90              Person ZhangSan = new Person()
91              {
92                  Age = 20,
93                  Name = "ZhangSan",
94                  Sex = "Boy"
95              };
96              this.DataContext = ZhanSan;
97  
98          }
WPF 数据验证第3张WPF 数据验证第4张UI代码
 1  <Window.Resources>
 2          <local:Converter x:Key="MarginConverter"></local:Converter>
 3          <Style TargetType="TextBox">
 4              <Setter Property="Width" Value="120"></Setter>
 5              <Setter Property="Margin" Value="5"></Setter>
 6              <Setter Property="VerticalAlignment" Value="Center"></Setter>
 7          </Style> 
 8          <Style TargetType="TextBlock">
 9              <Setter Property="MinWidth" Value="50"></Setter>
10              <Setter Property="Margin" Value="5"></Setter>
11              <Setter Property="VerticalAlignment" Value="Center"></Setter>
12          </Style>
13          <ControlTemplate x:Key="ErrorTemplate">
14              <Canvas Panel.ZIndex="100">
15                  <Border BorderBrush="Red" BorderThickness="1">
16                      <AdornedElementPlaceholder Name="MyAdorner"/>
17                  </Border>
18                  <TextBlock Foreground="Red" FontSize="12" 
19                             Margin="{Binding ElementName=MyAdorner, Path=ActualWidth, Converter={StaticResource MarginConverter}}"
20                             Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
21                  </TextBlock>
22              </Canvas>
23          </ControlTemplate>
24      </Window.Resources>
25 
26   <StackPanel>
27              <WrapPanel>
28                  <TextBlock>Name:</TextBlock>
29                  <TextBox Text="{Binding Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
30                           Validation.ErrorTemplate="{StaticResource ErrorTemplate}"></TextBox>
31                  <TextBlock>Age:</TextBlock>
32                  <TextBox  Validation.ErrorTemplate="{StaticResource ErrorTemplate}">
33                      <TextBox.Text>
34                          <Binding Path="Age"  ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged"
35                                   NotifyOnValidationError="True">
36                              <Binding.ValidationRules>
37                                  <local:AgeValidate MaxAge="99" MinAge="1"></local:AgeValidate>
38                              </Binding.ValidationRules>
39                          </Binding>
40                      </TextBox.Text>
41                  </TextBox>
42              </WrapPanel>
43              <WrapPanel>
44                  <TextBlock>Sex:</TextBlock>
45                  <TextBox Text="{Binding Path=Sex, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
46                           Validation.ErrorTemplate="{StaticResource ErrorTemplate}"></TextBox>
47              </WrapPanel>
48              <WrapPanel>
49                  <TextBlock>Age:</TextBlock>
50                  <TextBox Validation.ErrorTemplate="{StaticResource ErrorTemplate}">
51                      <TextBox.Text>
52                          <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True"> 
53                          </Binding>
54                      </TextBox.Text>
55                  </TextBox>
56              </WrapPanel> 
57  </StackPanel>
WPF 数据验证第5张WPF 数据验证第6张Converter Class
 1      public class Converter : IValueConverter
 2      {
 3          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 4          {
 5              if (value is double)
 6              {
 7                  return new Thickness((double)value + 5, 3, 5, 5);
 8              }
 9              else return value;
10          }
11  
12          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
13          {
14              throw new NotImplementedException();
15          }
16      }

注意:1. xaml中验证时机 UpdateSourceTrigger="PropertyChanged"表示属性修改后马上验证;

   2. ErrorTemplate 中TextBlock的 Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">的实现,这里Path=AdornedElement指的就是MyAdorner所装饰的元素,也就是我们需要验证的控件。因此获取的是该控件的(Validation.Errors)[0].ErrorContent 验证错误信息。

免责声明:文章转载自《WPF 数据验证》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JSON数据的处理中的特殊字符【Nginx(五)】Nginx配置Https证书下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

用docker启动的oracle,重启后数据库访问失败

昨天更改了oracle数据库的最大连接数,然后手动重启了docker,以为数据库就直接启动了,没想到报错了 报错类似于一下文章 https://blog.csdn.net/h106140873/article/details/103251534 SQL>startup ORA-00821: Specified value of sga_target...

不定字段数目的数据库表设计和数据结构

不定字段数目的数据库表设计和数据结构 可能采用四种技术: 动态增加数据库表字段 预留足够的空白字段,运行时作动态影射 用xml格式保存在单字段里 改列为行,用另外一个表存放定制字段 现在我们来分析一下四种技术的优劣,不过首先可以排除的是第一点动态增加字段的方法,因为在实际操作时候几乎是不可能的(sqlserver太慢,oracle索性不支持)...

jmeter数据驱动csv+批量导出数据到csv文件

基本的软件使用,我们简单一点,附图来讲,详细地方不懂的可以自行百度。 使用Jmeter 批量导入数据,之后批量导出数据到csv文件,可以帮助我们更好的整理数据,在工作中比较常用。 大致过程可以分三步:1. 导入csv文件;2. 变量引用; 3. 批量导出csv文件 1. 导入csv文件: point1:建议使用notpad, sublime等编辑器来编辑保...

WPF中ToolTip的自定义

ToolTip或者PopUp这个控件在做界面时会经常用到。如何对ToolTip进行自定义呢? 1.首先自定义tooltip的controlTemplate,完全清除系统默认效果, 如下:             <ControlTemplatex:Key="TooltipTemplate"TargetType="ToolTip">...

【转】使用Apache Kylin搭建企业级开源大数据分析平台

http://www.thebigdata.cn/JieJueFangAn/30143.html  本篇文章整理自史少锋4月23日在『1024大数据技术峰会』上的分享实录:使用Apache Kylin搭建企业级开源大数据分析平台。   正文如下   我先做一个简单介绍我叫史少锋,我曾经在IBM、eBay做过大数据、云架构的开发,现在是Kyligence的技...

Hibernate、批量操作数据

Hibernate 批量操作数据可以使用两种方法实现 1、分批更新,每一小批同步一次数据: public void saveEmployee2(){ Session s=HibernateSessionFactory.getSession(); Transaction tran=s.beginTransaction(); for...