WPF 数据验证

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

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

  

后台数据
 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          }
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>
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)