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

    运行结果以下:

  • 相关阅读:
    Netty 中的内存分配浅析-数据容器
    你想了解的 HTTPS 都在这里
    加解密算法分析
    HTTP 协议详解(二)
    HTTP 协议详解
    Netty 中的内存分配浅析
    TCP / IP 精彩回顾-必看
    Netty 中的消息解析和编解码器
    Netty 中的粘包和拆包
    python 类中方法总结 --- 实例方法、类方法、静态方法
  • 原文地址:https://www.cnblogs.com/3xiaolonglong/p/9777063.html
Copyright © 2011-2022 走看看