
上一篇,著重介紹了Silverlight客戶端同步數據驗證機制,演示了IDataErrorInfo接口的實現方法。在一些實際的Silverlight企業級項目中,我們經常會遇到通過服務對數據進行驗證,另外應用在驗證的同時,不會影響其他功能的運行,也就是我們常提及的異步操作,這樣的需求IDataErrorInfo接口和前期我們討論過的DataAnotation驗證機制都無法實現。另外在一些項目中,開發人員會綁定多個錯誤到一個數據成員,而IDataErrorInfo和DataAnotation也無法實現。Silverlight 4中,微軟引入一個新的接口INotifyDataErrorInfo,該接口的實現,可以輕松的解決以上兩個問題。
[INotifyDataErrorInfo接口](http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(VS.95).aspx)的概述
INotifyDataErrorInfo接口和IDataErrorInfo相同,命名空間都是System.ComponentModel。
該接口是為數據成員提供自定義的同步或者異步驗證支持。最常用的是對異步驗證的支持,另外,可支持單屬性中綁定多個錯誤信息。
INotifyDataErrorInfo接口具有一個屬性,一個方法,一個事件,分別是:
HasErrors, 這個屬性判斷當前對象中是否有錯誤,如果返回True則說明對象出現驗證錯誤,反之則False。
方法:
GetErrors, 這個方法負責返回特定驗證成員中所有的驗證錯誤信息,如果PropertyName參數為null或者string.empty,該方法將返回一個錯誤到全局對象中。
事件:
ErrorsChanged,該事件與上篇我們提及的PropertyChanged事件相似。當添加,刪除,修改驗證錯誤時,將激活該事件通知綁定系統,更新UI。
[INotifyDataErrorInfo接口](http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(VS.95).aspx)實例演示
實現INotifyDataErrorInfo接口,支持服務器端異步驗證,所以,本實例將創建一個Web服務,演示該接口驗證效果。
本篇實例,我們仍舊使用SilverlightValidationDemo項目,為了不和過去的驗證方法沖突,這里我們創建一個新的數據成員類Staff,該類實現INotifyDataErrorInfo接口和INotifyPropertyChanged接口. 其默認代碼如下,后面我們將逐漸完善這些代碼,
~~~
???????#region?INotifyDataErrorInfo?Members
????????public?event?EventHandler<DataErrorsChangedEventArgs>?ErrorsChanged;
????????public?System.Collections.IEnumerable?GetErrors(string?propertyName)
????????{
????????????throw?new?NotImplementedException();
????????}
????????public?bool?HasErrors
????????{
????????????get?{?throw?new?NotImplementedException();?}
????????}
????????#endregion
????????#region?INotifyPropertyChanged?Members
????????public?event?PropertyChangedEventHandler?PropertyChanged;
????????#endregion
~~~
另外定義一個新的數據成員,UserName
~~~
????????#region?data?memebers
????????private?string?_username;
????????public?string?UserName
????????{
????????????get?{?return?_username;?}
????????????set
????????????{
????????????????_username?=?value;
????????????}
????????}
????????#endregion
~~~
完成以上的客戶端準備步驟,我們首先到Web服務器端創建一個Silverlight enabled WCF Service, ValidationService。 這里我不再演示具體的創建步驟,如果不會創建的,請參考這里:[圖文詳解Silverlight訪問MSSQL數據庫](http://www.silverlightchina.net/html/tips/2009/1229/503.html)

在服務端,我們創建簡單的驗證代碼,如下
~~~
????[ServiceContract(Namespace?=?"")]
????[AspNetCompatibilityRequirements(RequirementsMode?=?AspNetCompatibilityRequirementsMode.Allowed)]
????public?class?ValidationService
????{
????????[OperationContract]
????????public?bool?ValidationUserName(string?username)
????????{
????????????if?(username?==?"jv9")
????????????????return?true;
????????????else
????????????????return?false;
????????}
????}
~~~
創建完畢后,編譯SilverlightValidationDemo.Web項目,然后回到Silverlight客戶端,添加一個新的服務引用,


搜索到剛創建的ValidationService服務,添加到客戶端,Visual Studio 2010會自動創建客戶端配置文件ServiceReferences.ClientConfig,

到這里一個WCF服務已經創建成功,下面,修改Staff類,
之前,我們已經創建了新的數據成員UserName,另外執行INotifyDataErrorInfo接口,自動生成ErrorsChanged事件,GetErrors方法和HasErrors屬性。
首先,需要對GetErrors方法進行重構,創建全局變量_validationErrors,承載驗證錯誤信息集合.
~~~
private?Dictionary<string,?ObservableCollection<string>>?_validationErrors;
????????public?System.Collections.IEnumerable?GetErrors(string?propertyName)
????????{
????????????if?(!string.IsNullOrEmpty(propertyName))
????????????{
????????????????if?(_validationErrors.ContainsKey(propertyName))
????????????????????return?_validationErrors[propertyName];
????????????????else
????????????????????return?null;
????????????}
????????????else
????????????????return?null;
????????}
~~~
然后,對HasErrors屬性進行重構,,判斷是否有驗證錯誤,
~~~
???????? public?bool?HasErrors
????????{
????????????get?
????????????{
????????????????foreach?(string?key?in?_validationErrors.Keys)
????????????????{
????????????????????if?(_validationErrors[key].Count?>?0)
????????????????????????return?true;
????????????????}
????????????????return?false;
????????????}
????????}
~~~
創建構造函數,和初始化錯誤集合,
~~~
????????public?Staff()
????????{
????????????_validationErrors?=?new?Dictionary<string,?ObservableCollection<string>>();
????????????GenerateErrorsCollection("UserName");
????????}
????????#endregion
????????#region?private?methods
????????private?void?GenerateErrorsCollection(string?propertyName)
????????{
????????????if?(!_validationErrors.ContainsKey(propertyName))
????????????{
????????????????_validationErrors.Add(propertyName,?new?ObservableCollection<string>());
????????????}
????????}
~~~
添加調用服務客戶端代碼,
~~~
????????private?void?ValidateUserNameandPasswordAsync(string?username)
????????{
????????????var?client?=?new?ValidationService.ValidationServiceClient();
????????????client.ValidationUserNameCompleted?+=?(o,?e)?=>
????????????{
????????????????_validationErrors["UserName"].Clear();
????????????????if?(e.Result)
????????????????{
????????????????????_username?=?username;
????????????????????NotifyPropertyChanged("UserName");
????????????????}
????????????????else
????????????????{
????????????????????_validationErrors["UserName"].Add("服務器端返回錯誤,用戶名必須是jv9");
????????????????}
????????????????if?(ErrorsChanged?!=?null)
????????????????{
????????????????????ErrorsChanged(this,?new?DataErrorsChangedEventArgs("UserName"));
????????????????}
????????????};
????????????client.ValidationUserNameAsync(username);
????????}
~~~
在數據成員中,添加驗證方法調用,
~~~
????????#region?data?memebers
????????private?string?_username;
????????public?string?UserName
????????{
????????????get?{?return?_username;?}
????????????set
????????????{
????????????????_username?=?value;
????????????????ValidateUserNameandPasswordAsync(value);
????????????}
????????}
????????#endregion
~~~
其運行效果:

在每次修改用戶框內容后,應用會自動向WCF服務請求驗證,如果驗證失敗,則彈出驗證錯誤信息,反之,則繼續。
INotifyPropertyChanged接口,相比前面介紹的幾個驗證機制,其復雜程度較高,需要開發人員設計部分代碼,但是其異步服務器端數據驗證功能和單一屬性添加多個錯誤信息功能,是Silverlight企業級項目中常用到的功能。在隨后的項目中,我們會使用更多實例演示其強大功能。
今天就到這里了。
[源代碼下載](http://www.silverlightchina.net/uploads/soft/100914/1-100914200150.rar)
歡迎大家加入"專注Silverlight" 技術討論群:
32679955(六群)
23413513(五群)
32679922(四群)
100844510(三群)
37891947(二群)
22308706(一群)
?
?
- 前言
- 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導航框架傳遞參數