
[Silverlight Validation驗證實例教程系列](http://www.silverlightchina.net/html/zhuantixilie/getstart/2010/0924/2035.html)已經寫了[七篇](http://www.cnblogs.com/jv9/)了,今天將完成計劃中的最后一個話題,創建自定義擴展驗證類,本篇是根據一些讀者反饋的問題總結而來的,在本篇最后,將簡單的對目前Silverlight Validation驗證框架提供的驗證機制進行總結性的對比和歸納,希望能夠幫助大家在實際項目中定位和應用驗證框架。
閱讀過[前幾篇Silverlight實例教程](http://www.silverlightchina.net/html/zhuantixilie/getstart/2010/0924/2035.html)的朋友,給我留言和來信,大家對于Silverlight Validation類的使用,總感覺有些不靈活,特別是在自定義使用時,很難輕松的控制錯誤驗證的捕獲和彈出。 下面,我將演示另外一個實例,該實例將幫助開發人員創建自定義擴展Validation類,該類允許開發人員,方便的控制驗證錯誤彈出,驗證錯誤清除,以及驗證校驗方法。
**Silverlight Validation自定義擴展類**
本實例仍舊使用SilverlightValidationDemo項目,在Mainpage中創建一個簡單的UI,進行演示:

[](http://images.cnblogs.com/cnblogs_com/jv9/WindowsLiveWriter/SilverlightValidation_D5A9/image_2.png)
~~~
<StackPanel?Margin="5">?
?????????????????<StackPanel?Orientation="Horizontal"?Margin="5">?
????????????????<TextBlock?Text="產品名:?"?VerticalAlignment="Center"/>?
????????????????<TextBox?x:Name="txtProduct"?Width="200"?/>?
????????????</StackPanel>?
????????????<StackPanel?Orientation="Horizontal"?Margin="5">?
????????????????<TextBlock?Text="數??量:?"?VerticalAlignment="Center"/>?
????????????????<TextBox?x:Name="txtAmount"?Width="200"??/>?
????????????</StackPanel>?
????????????<StackPanel?Orientation="Horizontal"?Margin="5">?
????????????????<TextBlock?Text="單??價:?"?VerticalAlignment="Center"/>?
????????????????<TextBox?x:Name="txtPrice"?Width="200"?/>?
????????????</StackPanel>?
????????????<StackPanel?Orientation="Horizontal"?>?
????????????????<Button?x:Name="btBuy"?Content="購??買"?Margin="5"?/>?
????????????????<Button?x:Name="btReset"?Content="重??置"?Margin="5"?/>?
????????????</StackPanel>?
</StackPanel>
~~~
根據上圖,我們看到,我們將對產品名,產品數量和產品單價進行驗證,在Xaml代碼中,沒有對Text進行綁定,這些,我們將在代碼中進行實現。
在完成上面UI的創建,我們需要創建一個靜態類ValidationExtension,在該類中,我們將創建自定義驗證方法,以及驗證錯誤信息控制方法。
在ValidationExtension類中,我們將使用以下三個靜態方法,接管Silverlight Validation默認的驗證捕獲,其代碼分別是:
~~~
public?static?void?SetValidation(this?FrameworkElement?frameworkElement,?string?message)?
{?
????????????CustomizeValidation?customValidation?=?new?CustomizeValidation(message);?
????????????Binding?binding?=?new?Binding("ValidationError")?
????????????{?
????????????????Mode?=?System.Windows.Data.BindingMode.TwoWay,?
????????????????NotifyOnValidationError?=?true,?
????????????????ValidatesOnExceptions?=?true,?
????????????????Source?=?customValidation?
????????????};?
????????????frameworkElement.SetBinding(Control.TagProperty,?binding);?
}
~~~
SetValidation靜態方法,將設置FrameworkElement元素綁定ValidationError驗證錯誤信息,其中設置NotifyOnValidationError 和ValidatesOnExceptions 為True,允許控件對異常和驗證錯誤進行捕獲和反饋。
~~~
public?static?void?RaiseValidationError(this?FrameworkElement?frameworkElement)?
????????{?
????????????BindingExpression?b?=?frameworkElement.GetBindingExpression(Control.TagProperty);?
????????????if?(b?!=?null)?
????????????{?
????????????????((CustomizeValidation)b.DataItem).ShowErrorMessage?=?true;?
????????????????b.UpdateSource();?
????????????}?
????????}
~~~
RaiseValidationError靜態方法,在驗證錯誤綁定后,通過該方法將錯誤異常顯示在客戶端,通過UpdateSource方法更新客戶端錯誤異常顯示。簡單的理解就是在客戶端控件對象,彈出異常錯誤提示信息。
~~~
public?static?void?ClearValidationError(this?FrameworkElement?frameworkElement)?
????????{?
????????????BindingExpression?b?=?frameworkElement.GetBindingExpression(Control.TagProperty);?
????????????if?(b?!=?null)?
????????????{?
????????????????((CustomizeValidation)b.DataItem).ShowErrorMessage?=?false;?
????????????????b.UpdateSource();?
????????????}?
????????}
~~~
ClearValidationError靜態方法,和RaiseValidationError靜態方法正好相反,調用該方法將清空當前對象上顯示的異常錯誤信息。
以上三個方法的調用,將在后文演示。下面需要添加簡單的驗證條件,幫助客戶端捕獲驗證錯誤信息,為了方便起見,這里,創建了對數字的判斷和對雙精度型的數據判斷,代碼如下:
~~~
public?static?bool?IsNumberValid(this?string?inputNumber)?
????????{?
????????????bool?isNumberValid?=?true;?
????????????int?number?=?-1;?
????????????if?(!Int32.TryParse(inputNumber,?out?number))?
????????????{?
????????????????isNumberValid?=?false;?
????????????}?
????????????return?isNumberValid;?
????????}?
~~~
IsNumberValid靜態方法,判斷當前對象中輸入字符是否為數字;
~~~
public?static?bool?IsPriceValid(this?string?inputPrice)?
????????{?
????????????bool?isPriceValid?=?true;?
????????????double?minprice?=?8.8;?
????????????if?(Convert.ToDouble(inputPrice)?<?minprice)?
????????????{?
????????????????isPriceValid?=?false;?
????????????}?
????????????return?isPriceValid;?
????????}?
~~~
IsPriceValid靜態方法,判斷當前對象中輸入字符是否大于最小價格,如果False,則返回驗證錯誤。
這里大家已經留意到,ValidationExtension自定義擴展類沒有繼承和實現任何驗證類或接口,獨立存在。
在以上靜態方法中,我們用到了CustomizeValidation自定義驗證類中的屬性成員,在過去的幾篇中,我們僅在CustomizeValidation中定義了一個簡單的自定義驗證方法,而現在我們需要添加兩個簡單的屬性和一個新的構造函數,其代碼如下:
~~~
#region?Private?memebers?
????????private?string?message;?
????????#endregion?
????????#region?Public?Property?
????????public?bool?ShowErrorMessage?
????????{?
????????????get;?
????????????set;?
????????}?
????????public?object?ValidationError?
????????{?
????????????get?
????????????{?
????????????????return?null;?
????????????}?
????????????set?
????????????{?
????????????????if?(ShowErrorMessage)?
????????????????{?
????????????????????throw?new?ValidationException(message);?
????????????????}?
????????????}?
????????}?
#endregion
~~~
構造函數:
~~~
public?CustomizeValidation(string?message)?
????????{?
????????????this.message?=?message;?
????????}
~~~
其目的是為了收集驗證錯誤信息。
完成了以上自定義代碼后,我們可以在客戶端進行簡單的調用代碼設置:
目前,我們希望,點擊“購買”按鈕后,對用戶輸入信息進行驗證判斷,如果有錯誤異常,則彈出驗證錯誤信息,
這里我們僅需要添加部分代碼到btBuy.Click事件即可。
~~~
#region?Validation?Extension?
????????private?void?btBuy_Click(object?sender,?RoutedEventArgs?e)?
????????{?
????????????bool?isValid?=?true;?
????????????txtProduct.ClearValidationError();?
????????????txtAmount.ClearValidationError();?
????????????txtPrice.ClearValidationError();?
????????????if?(txtProduct.Text?==?"")?
????????????{?
????????????????txtProduct.SetValidation("請輸入產品名稱");?
????????????????txtProduct.RaiseValidationError();?
????????????????isValid?=?false;?
????????????}?
????????????if?(txtAmount.Text?==?""?||?!txtAmount.Text.IsNumberValid())?
????????????{?
????????????????txtAmount.SetValidation("請輸入一個整數");?
????????????????txtAmount.RaiseValidationError();?
????????????????isValid?=?false;?
????????????}?
????????????if?(txtPrice.Text?==?""?||?!txtPrice.Text.IsPriceValid())?
????????????{?
????????????????txtPrice.SetValidation("最小出價8.8");?
????????????????txtPrice.RaiseValidationError();?
????????????????isValid?=?false;?
????????????}?
????????????if?(isValid)?
????????????{?
????????????????HtmlPage.Window.Alert("產品購買成功");?
????????????????ResetForm();?
????????????}?
????????}?
????????private?void?btReset_Click(object?sender,?RoutedEventArgs?e)?
????????{?
????????????ResetForm();?
????????}?
????????private?void?ResetForm()?
????????{
?????????????txtProduct.ClearValidationError();?
????????????txtAmount.ClearValidationError();?
????????????txtPrice.ClearValidationError();?
????????????txtProduct.Text?=?"";?
????????????txtAmount.Text?=?"";?
????????????txtPrice.Text?=?"";?
????????}?
#endregion
~~~
通過SetValidation,設置驗證錯誤提示信息,通過RaiseValidationError彈出驗證錯誤信息,每次點擊前,調用ClearValidationError清空當前驗證錯誤。最終執行結果如下:

[](http://images.cnblogs.com/cnblogs_com/jv9/WindowsLiveWriter/SilverlightValidation_D5A9/image_4.png)
到這里,我們已經完成了一個自定義擴展Validation類,大家可以根據這個思路擴展更多的驗證校驗方法,并應用到項目控件中。
**Silverlight Validation驗證機制對比總結和建議**
在過去的幾篇中,我們曾經詳細介紹了四種Silverlight Validation驗證機制,分別是
基本異常驗證機制;
DataAnnotation驗證機制;
IDataErrorInfo客戶端同步驗證機制;
INotifyDataErrorInfo服務器端異步驗證機制;
一些朋友發郵件問我,這些驗證機制在項目中的優勢是什么?在實際項目中,如何選擇適當的驗證機制?下面有個簡單的列表,將以上四種驗證機制進行簡單的歸納總結:
<table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td width="130"><p align="center"><strong>驗證機制</strong></p></td><td width="237"><p align="center"><strong>優勢</strong></p></td><td width="183"><p align="center"><strong>劣勢</strong></p></td></tr><tr><td width="130"><p>基本異常驗證機制</p></td><td width="237"><p>1. 適用任何數據類型驗證;</p><p>2. 使用方法簡單,僅需在Xaml代碼中設置即可;</p></td><td width="183"><p>1. 只能在屬性Setter中使用;</p><p>2. 不支持自定義方法驗證</p><p>3. 每個成員每次僅能捕獲一個驗證錯誤</p></td></tr><tr><td width="130"><p>DataAnnotation驗證機制</p></td><td width="237"><p>1. 不會引發異常錯誤;</p><p>2. 每個成員可以使用多個驗證條件;</p><p>3. 使用方法簡單,僅需聲明屬性即可;無需過多編寫代碼;</p><p>4. 支持自定義方法驗證;</p></td><td width="183"><p>僅適合用于Datagrid和Dataform和一些可使用DataAnnotation屬性的第三方控件</p></td></tr><tr><td width="130"><p>IDataErrorInfo客戶端同步驗證機制</p></td><td width="237"><p>1. 不會引發異常錯誤;</p><p>2. 支持自定義方法驗證;</p></td><td width="183"><p>1. 不能捕獲數據類型驗證錯誤;</p><p>2. 每個數據成員每次僅能捕獲一個驗證錯誤;</p><p>3. 使用方法較為復雜;</p></td></tr><tr><td width="130"><p>INotifyDataErrorInfo服務器端異步驗證機制</p></td><td width="237"><p>1. 不會引發異常錯誤;</p><p>2. 支持自定義方法驗證;</p><p>3. 支持服務器端異步驗證;</p><p>4. 每個成員可以使用多個驗證條件;</p></td><td width="183"><p>1. 不能捕獲數據類型驗證錯誤;</p><p>2. 多條件驗證下,僅支持顯示第一個驗證錯誤;</p><p>3. 使用方法復雜;</p></td></tr></tbody></table>
?
在使用Silverlight Validation框架是需要注意以下幾點:
?
1. 使項目支持異常捕獲,這樣驗證框架可支持數據類型校驗;
2. 如果使用Datagrid和Dataform控件,推薦使用DataAnnotation驗證機制;
3. 如果需要在客戶端驗證所有信息,推薦使用IDataErrorInfo驗證機制;
4. 如果需要使用服務器端的驗證方法,推薦使用INotifyDataErrorInfo驗證機制。
?
相信大家在明白了以上各個驗證機制的優勢和劣勢后,已經可以輕松掌握Silverlight Validation驗證框架的應用了。
[Silverlight Validation實例教程系列](http://www.silverlightchina.net/html/zhuantixilie/getstart/2010/0924/2035.html),到這里即將完結,如果大家在閱讀中,或者項目中遇到問題或者有不同的意見,
歡迎留言給我,我們一起討論學習。
最后感謝每一位支持的朋友。
[源代碼下載](http://www.silverlightchina.net/resource/code/2010/SilverlightValidationDemo.rar)
歡迎大家加入“專注Silverlight”QQ技術群,目前,1-6群都已經滿員,新開500人七群,歡迎大家加入一起學習討論Silverlight&WPF開發技術。?
22308706(一群) 超級群500人滿?
37891947(二群) 超級群500人滿?
100844510(三群) 高級群200人滿?
32679922(四群) 超級群500人滿?
23413513(五群) 高級群200人滿?
32679955(六群) 超級群500人滿?
61267622(七群 推薦) 超級群500人未滿
?
- 前言
- Out of Browser開篇
- Out of Browser配置,安裝和卸載
- Out of Browser的自定義應用
- Out of Browser存取本地文件系統
- Out of Browser與COM的交互基礎
- Out of Browser與Office的互操作
- Out of Browser的Debug和Notifications窗口
- Out of Browser音樂播放器
- Out of Browser與COM互操作實例
- Out of Browser在線更新和Silent安裝
- Validation數據驗證開篇
- Validation數據驗證基礎屬性和事件
- Validation數據驗證DataAnnotation機制和調試技巧
- Validation服務器端異步數據驗證
- Validation客戶端同步數據驗證
- Validation用戶提交數據驗證捕獲
- Datagrid,Dataform數據驗證和ValidationSummary
- 自定義擴展Validation類,驗證框架的總結和建議
- Navigation導航框架開篇
- 理解Navigation導航框架Frame類
- 理解Navigation導航框架Page類
- Navigation導航框架URI映射機制
- Navigation導航框架傳遞參數