轉(zhuǎn)帖|其它|編輯:郝浩|2011-03-31 13:57:12.000|閱讀 1729 次
概述:在我們綁定完數(shù)據(jù)后,在用戶輸入數(shù)據(jù)后,還需要進(jìn)行用戶輸入合法性驗(yàn)證,比如需要判斷 必填項(xiàng),email地址輸入格式,日期格式是否正確等。wpf為我們提供了一種驗(yàn)證用戶合法行的方式。依賴于綁定。在將實(shí)體數(shù)據(jù)綁定到視圖后,如果用戶輸入的視圖改變,則同時(shí)通知實(shí)體的屬性值改變。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在我們綁定完數(shù)據(jù)后,在用戶輸入數(shù)據(jù)后,還需要進(jìn)行用戶輸入合法性驗(yàn)證,比如需要判斷 必填項(xiàng),email地址輸入格式,日期格式是否正確等。
wpf為我們提供了一種驗(yàn)證用戶合法行的方式。依賴于綁定。在將實(shí)體數(shù)據(jù)綁定到視圖后,如果用戶輸入的視圖改變,則同時(shí)通知實(shí)體的屬性值改變。先看代碼:
1. 構(gòu)建一個(gè)要綁定到界面的實(shí)體。該實(shí)體實(shí)現(xiàn)了IDataErrorInfo接口,在接口里寫了驗(yàn)證規(guī)則。
//實(shí)體 實(shí)現(xiàn) IDataErrorInfo接口,并在 this[]索引器里定制自己的驗(yàn)證規(guī)則
using System.ComponentModel;
namespace TextVerify
{
partial class eva:IDataErrorInfo
{
string _err;
public string Error
{
get { return _err; }
}
//定制驗(yàn)證規(guī)則
public string this[string columnName]
{
get
{
string err = "";
switch (columnName)
{
case "Name":
if (string.IsNullOrEmpty(this.Name))
{
err = "名稱不能為空";
}
else
{
if (this.Name.Length > 8)
{
err = "名稱太長(zhǎng)了,不能大于8個(gè)字符";
}
}
break;
case "Value":
if (this.value < 0 || this.value > 200)
{
err = "數(shù)字不合法";
}
break;
}
_err = err;
return _err;
}
}
}
}
2.頁面:
<Window x:Class="TextVerify.MainWindow"
xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x= "//schemas.microsoft.com/winfx/2006/xaml"
Title= "MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid Name="eee">
<TextBox Height="23" HorizontalAlignment="Left"
Margin="152,73,0,0" Name="name"
Text="{Binding Path=Name, Mode=TwoWay,UpdateSourceTrigger=
'PropertyChanged',ValidatesOnDataErrors=True}"
VerticalAlignment= "Top" Width="120" >
<Validation.ErrorTemplate>
<ControlTemplate>
<!-- ControlTemplate要求只能有一個(gè)子級(jí),所以加個(gè)容器控件DockPanel -->
<DockPanel>
<!-- AdornedElementPlaceholder就是要驗(yàn)證的控件本身,本例里是個(gè)TextBox -->
<AdornedElementPlaceholder />
<TextBlock Foreground="Red" FontSize="20" Text="*" />
</DockPanel>
</ControlTemplate>
</Validation.ErrorTemplate>
</TextBox>
<Button Content="保 存" Height="23"
HorizontalAlignment="Left" Margin="152,114,0,0"
Name="button1"
VerticalAlignment= "Top" Width="75" Click="button1_Click" />
</Grid>
</Window>
32
頁面的后臺(tái)代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TextVerify
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
// EvaDAO ed = new EvaDAO();
// eva er = new eva();
public MainWindow(){}
//public MainWindow(eva er)
//{
// InitializeComponent();
// //eee.DataContext = er;
//}
/// <summary>
/// 保存
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, RoutedEventArgs e)
{
//if(name.Text== "" || name.Text==""){
// return;
//}
//er.Name = name.Text;
//er.value = 222222;
////MessageBox.Show(er+ "===");
//ed.Save(er);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
eee.DataContext = GetEvaFromDatabase();
}
private eva GetEvaFromDatabase()
{
//從數(shù)據(jù)庫獲得數(shù)據(jù)對(duì)象 <演示>
return new eva() { Name = "sa", value = 123 };
}
}
}
按F5運(yùn)行后,嘗試輸入寫不合法數(shù)據(jù)。可以看到Textbox的邊框變成紅色。這是一種默認(rèn)的提示錯(cuò)誤的風(fēng)格方式,我們還可以對(duì)這個(gè)提示風(fēng)格進(jìn)行自定義。
注意Binding的下面兩個(gè)屬性:
ValidatesOnDataErrors 獲取或設(shè)置一個(gè)值,該值指示是否包含 DataErrorValidationRule。
ValidationRules 獲取用于檢查用戶輸入有效性的規(guī)則集合。
也就是說當(dāng)我們?cè)O(shè)置了 Binding的ValidatesOnDataErrors="True" 時(shí)。WPF框架在構(gòu)造Binding對(duì)象時(shí),會(huì)自動(dòng)的添加一個(gè)默認(rèn)的DataErrorValidationRule到ValidationRules 屬性值(驗(yàn)證規(guī)則列表)內(nèi)。或者我們直接在ValidationRules 里添加我們需要的規(guī)則,比如下面是添加了兩個(gè)規(guī)則:
<Binding.ValidationRules>
<DataErrorValidationRule />
<ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>
這樣的寫法很有意思,貌似IOC的方式配置文件,比如spring.Net的配置文件,這樣的聲明ValidationRules的包含的規(guī)則。當(dāng)WPF框架創(chuàng)建對(duì)象時(shí)自動(dòng)的完成規(guī)則操作,并判斷ValidationRules內(nèi)的規(guī)則數(shù)量,如果多于0個(gè),就遍歷所有的規(guī)則集合,如果集合中包含了DataErrorValidationRule 并且實(shí)體類顯示了IDataErrorInfo
接口,就調(diào)用 實(shí)體內(nèi)包含的 驗(yàn)證規(guī)則。
ExceptionValidationRule 類是一個(gè)內(nèi)置的規(guī)則,它檢查在綁定源屬性更新過程中引發(fā)的異常。這里驗(yàn)證了Age的用戶輸入不可為空,當(dāng)為空時(shí),轉(zhuǎn)型成int(Age是int類型)時(shí)就會(huì)出錯(cuò)。
通過創(chuàng)建一個(gè)從 ValidationRule 派生的類,可以創(chuàng)建自定義規(guī)則。下面我嘗試自定義驗(yàn)證規(guī)則。
MSDN里對(duì)ValidateionRule的描述如下:
在使用 WPF 數(shù)據(jù)綁定模型時(shí),可將 ValidationRules 與綁定對(duì)象關(guān)聯(lián)。若要?jiǎng)?chuàng)建自定義規(guī)則,請(qǐng)創(chuàng)建此類的子類并實(shí)現(xiàn) Validate 方法。也可選擇使用內(nèi)置的 ExceptionValidationRule(該類捕獲在源更新期間引發(fā)的異常)或 DataErrorValidationRule(該類檢查源對(duì)象的 IDataErrorInfo 實(shí)現(xiàn)所引發(fā)的錯(cuò)誤)。
綁定引擎在每次將輸入值(即綁定目標(biāo)屬性值)傳給綁定源屬性時(shí)將檢查與綁定關(guān)聯(lián)的每一個(gè) ValidationRule。
頁面xaml代碼如下,而后置代碼不變。
下面我們看看如何更改在驗(yàn)證失敗時(shí)的提示風(fēng)格
<Window x:Class="TextVerify.MainWindow"
xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x= "//schemas.microsoft.com/winfx/2006/xaml"
Title= "MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid Name="eee">
<TextBox Height="23" HorizontalAlignment="Left"
Margin="152,73,0,0" Name="name"
Text="{Binding Path=Name, Mode=TwoWay,UpdateSourceTrigger=
'PropertyChanged',ValidatesOnDataErrors=True}"
VerticalAlignment= "Top" Width="120" >
<Validation.ErrorTemplate>
<ControlTemplate>
<!-- ControlTemplate要求只能有一個(gè)子級(jí),所以加個(gè)容器控件DockPanel -->
<DockPanel>
<!-- AdornedElementPlaceholder就是要驗(yàn)證的控件本身,本例里是個(gè)TextBox -->
<AdornedElementPlaceholder />
<TextBlock Foreground="Red" FontSize="20" Text="*" />
</DockPanel>
</ControlTemplate>
</Validation.ErrorTemplate>
</TextBox>
<Button Content="保 存" Height="23" HorizontalAlignment="Left" Margin="152,114,0,0"
Name= "button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
<Window.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="#DDD" />
<Setter Property="Foreground" Value="Red" />
<Setter Property="ToolTip"
Value= "{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
</Window>
我們注意到Textbox.Validation屬性的ErrorTemplate是發(fā)生錯(cuò)誤時(shí)使用的模板,我們重新new了一個(gè)ControlTemplate來代替這個(gè)模板。在這個(gè)模板里我們定義了一個(gè)DockPanel作為容器控件,使用 占位標(biāo)記AdornedElementPlaceholder 標(biāo)記了TextBox的位置,并在它后面添加兩個(gè) 字符"*"號(hào)。這可能有點(diǎn)難以理解。換個(gè)說法是,每個(gè)TextBox都有個(gè)Validation屬性,Validation包含了一些和驗(yàn)證相關(guān)的像,包含有個(gè)當(dāng)驗(yàn)證失敗時(shí)的顯示模板。而我們重新定義了個(gè)顯示模板。這個(gè)模板里有個(gè)占位符,占位符表示TextBox本身,我們?cè)谶@個(gè)模板的占位符后面添加一些字符 紅色的"*" 號(hào)。那么當(dāng)TextBox在執(zhí)行時(shí),如果失敗,就會(huì)把 錯(cuò)誤模板 顯示出來,并在 占位符位置 顯示自己。
我們換個(gè)另外的方式來改變視圖效果,使用style 方式。
在窗體資源里添加一個(gè)style,style這個(gè)東西呢,類似web開發(fā)中的css。他有個(gè)屬性TargetType 指示了這個(gè)樣式的作用域。本例中指示了 所有的TextBox,style的強(qiáng)大之處還有個(gè)Triggers就是觸發(fā)器。本例中觸發(fā)器指向一個(gè)屬性Validation.HasError屬性,當(dāng)這屬性的值為"True"時(shí),觸發(fā)Trigger包含的樣式。當(dāng)不等于"True"時(shí),自動(dòng)改回原來的樣式。很強(qiáng)大吧。Setter元素提供了設(shè)置目標(biāo)對(duì)象屬性的方法,我們直接更改了Textbox.ToolTop屬性,那么當(dāng)鼠標(biāo)移動(dòng)到控件上時(shí),就會(huì)顯示發(fā)生錯(cuò)誤的原因。
1<Window.Resources>
2 <Style TargetType="TextBox">
3 <Style.Triggers>
4 <Trigger Property="Validation.HasError" Value="True">
5 <Setter Property="Background" Value="#DDD" />
6 <Setter Property="Foreground" Value="Red" />
7 <Setter Property="ToolTip"
8 Value= "{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
9 </Trigger>
10 </Style.Triggers>
11 </Style>
12 </Window.Resources>
這句
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"/>
完成了獲得關(guān)聯(lián)數(shù)據(jù)源,并綁定錯(cuò)誤提示的操作。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)易博客