zoukankan      html  css  js  c++  java
  • WPF---数据绑定之ValidationRule数据校验(六)

    一、概述

    我们知道,Binding好比架设在Source和Target之间的桥梁,数据可以借助这个桥梁进行流通。在数据流通的过程中,我们可以在Binding这座桥梁上设置关卡,对数据的有效性进行验证。

    二、验证方法

    我们利用Binding的ValidationRules(类型为Collection<ValidationRule)对数据进行验证。从它的名称和类型可以得知,我们可以为每个Binding设置多个数据校验条件,每个条件是一个

    ValidationRule对象,ValidationRule类是个抽象类,使用的时候,我们需要创建它的派生类并实现它的Validate方法

    Validate方法返回值是ValidationResult类型对象,如果校验通过,需要把ValidationResult对象的IsValid属性设置为true,反之,设置false并为其ErrorContent属性设置一个合适的消息内容,一般情况下是一个字符串。

    三、例子

    Demo1

    假设UI上有一个Slider和一个TextBox,我们以Slider为源,TextBox为Target,Slider的取值范围为0~100,也就是说我们要需要校验TextBox中输入的值是不是在1~100这个范围内。

     1 using System.Globalization;
     2 using System.Windows;
     3 using System.Windows.Controls;
     4 
     5 namespace BindingDemo4ValidationRule
     6 {
     7     /// <summary>
     8     /// Interaction logic for MainWindow.xaml
     9     /// </summary>
    10     public partial class MainWindow : Window
    11     {
    12         public MainWindow()
    13         {
    14             InitializeComponent();
    15         }
    16     }
    17     public class RangeValidationRule:ValidationRule
    18     {
    19         public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    20         {
    21             double myValue = 0;
    22             if(double.TryParse(value.ToString(),out myValue))
    23             {
    24                 if (myValue >= 0 && myValue <= 100)
    25                 {
    26                     return new ValidationResult(true, null);
    27                 }
    28             }
    29             return new ValidationResult(false, "Input should between 0 and 100");
    30         }
    31     }
    32 }
    View Code
     1 <Window x:Class="BindingDemo4ValidationRule.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     6         xmlns:local="clr-namespace:BindingDemo4ValidationRule"
     7         mc:Ignorable="d"
     8         Title="MainWindow" Height="350" Width="525">
     9     <Grid>
    10         <Slider Margin="10,120,-10,-120" Minimum="0" Maximum="100" Name="slider" Value="10"></Slider>
    11         <TextBox Height="50" Margin="5,30,5,240" >
    12             <TextBox.Text>
    13                 <Binding ElementName="slider" Path="Value" UpdateSourceTrigger="PropertyChanged">
    14                     <Binding.ValidationRules>
    15                         <local:RangeValidationRule/>
    16                     </Binding.ValidationRules>
    17                 </Binding>
    18             </TextBox.Text>
    19         </TextBox>
    20       
    21     </Grid>
    22 </Window>
    View Code

    运行结果如下:

     从结果中可以看出,当我们在TextBox中输入的值不在0~100的范围内的时候,TextBox会显示红色边框,提示值是错误的。

    Demo2

    默认情况下,Binding校验默认来自Source的数据总是正确的,只有来自Target的数据(Target多为UI控件,等价于用户的输入)才有可能出现问题,为了不让有问题的数据污染Source,所以需要校验。换句话说,Binding只在Target被外部更新时候进行校验,而来自Binding的Source数据更新Target时是不会进行校验的。

    当来自Source的数据也有可能出现问题的时候,我们需要将校验条件的ValidatesOnTargetUpdated属性设置为true。

    我们把Xaml代码改为以下的时候,会发现当移动滑动条在0以下或者100以上的时候,TextBox边框也会变成红色。

     1 <Window x:Class="BindingDemo4ValidationRule.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     6         xmlns:local="clr-namespace:BindingDemo4ValidationRule"
     7         mc:Ignorable="d"
     8         Title="MainWindow" Height="350" Width="525">
     9     <Grid>
    10         <Slider Margin="10,120,10,-120" Minimum="-10" Maximum="110" Name="slider" Value="10"></Slider>
    11         <TextBox Height="50" Margin="5,30,5,240" >
    12             <TextBox.Text>
    13                 <Binding ElementName="slider" Path="Value" UpdateSourceTrigger="PropertyChanged">
    14                     <Binding.ValidationRules>
    15                         <local:RangeValidationRule ValidatesOnTargetUpdated="True"/>
    16                     </Binding.ValidationRules>
    17                 </Binding>
    18             </TextBox.Text>
    19         </TextBox>
    20       
    21     </Grid>
    22 </Window>

    Demo3

    当校验发生错误的时候,Validate方法返回的ValidationResult对象会携带一条错误消息,下面我们就要显示这个错误消息。

    为了达到这个目的,我们需要把Binding的NotifyOnValidationError属性设置为true,这样当数据校验失败的时候,Binding会像报警一样发出一个信号,这个信号会以Binding对象的Target为起点在UI树上传播,如果某个节点上设置了对这种信号的侦听器,那么这个侦听器就会触发来处理这个信号。详细参加以下代码:

     1 using System.Globalization;
     2 using System.Windows;
     3 using System.Windows.Controls;
     4 
     5 namespace BindingDemo4ValidationRule
     6 {
     7     /// <summary>
     8     /// Interaction logic for MainWindow.xaml
     9     /// </summary>
    10     public partial class MainWindow : Window
    11     {
    12         public string TipMessage
    13         {
    14             get { return (string)GetValue(TipMessageProperty); }
    15             set { SetValue(TipMessageProperty, value); }
    16         }
    17 
    18         // Using a DependencyProperty as the backing store for TipMessage.  This enables animation, styling, binding, etc...
    19         public static readonly DependencyProperty TipMessageProperty =
    20             DependencyProperty.Register("TipMessage", typeof(string), typeof(MainWindow), new PropertyMetadata("Tip"));
    21 
    22         public MainWindow()
    23         {
    24             InitializeComponent();
    25             this.DataContext = this;
    26         }
    27 
    28         private void tbx1_Error(object sender, ValidationErrorEventArgs e)
    29         {
    30             if (Validation.GetErrors(tbx1).Count > 0)
    31             {
    32                 TipMessage = Validation.GetErrors(tbx1)[0].ErrorContent.ToString();
    33             }
    34             else
    35             {
    36                 TipMessage = "";
    37             }
    38         }
    39     }
    40     public class RangeValidationRule : ValidationRule
    41     {
    42         public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    43         {
    44             double myValue = 0;
    45             if (double.TryParse(value.ToString(), out myValue))
    46             {
    47                 if (myValue >= 0 && myValue <= 100)
    48                 {
    49                     return new ValidationResult(true, null);
    50                 }
    51             }
    52 
    53             return new ValidationResult(false, "Input should between 0 and 100");
    54         }
    55     }
    56 }
    View Code
     1 <Window x:Class="BindingDemo4ValidationRule.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     6         xmlns:local="clr-namespace:BindingDemo4ValidationRule"
     7         mc:Ignorable="d"
     8         Title="MainWindow" Height="350" Width="525">
     9     <Grid>
    10         <Slider Margin="10,120,10,-120" Minimum="-10" Maximum="110" Name="slider" Value="10"></Slider>
    11         <TextBox Height="50" Margin="5,30,5,240" Name="tbx1" Validation.Error="tbx1_Error">
    12             <TextBox.Text>
    13                 <Binding ElementName="slider" Path="Value" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
    14                     <Binding.ValidationRules>
    15                         <local:RangeValidationRule ValidatesOnTargetUpdated="True"/>
    16                     </Binding.ValidationRules>
    17                 </Binding>
    18             </TextBox.Text>
    19         </TextBox>
    20         <Label Height="50" Margin="5,154,-5,116" Content="{Binding TipMessage}" Foreground="Red"> 
    21             
    22         </Label>
    23       
    24     </Grid>
    25 </Window>
    View Code

    运行结果以下:

  • 相关阅读:
    cf B. Sereja and Suffixes
    cf E. Dima and Magic Guitar
    cf D. Dima and Trap Graph
    cf C. Dima and Salad
    最短路径问题(floyd)
    Drainage Ditches(网络流(EK算法))
    图结构练习—BFSDFS—判断可达性(BFS)
    Sorting It All Out(拓扑排序)
    Power Network(最大流(EK算法))
    Labeling Balls(拓扑)
  • 原文地址:https://www.cnblogs.com/3xiaolonglong/p/9777063.html
Copyright © 2011-2022 走看看