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

運行結果以下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM