WPF使用ValidationRules對(duì)MVVM架構(gòu)數(shù)據(jù)驗(yàn)證
對(duì)于WPF中的驗(yàn)證, View驗(yàn)證實(shí)現(xiàn)起來(lái)很簡(jiǎn)單, 可以通道 Validation.ErrorEvent 冒泡傳遞到View的邏輯樹(shù)上, 只是, 通常這樣做的情況下, 我們需要為View添加事件代碼監(jiān)聽(tīng)這類錯(cuò)誤事件, 然后進(jìn)行處理。
這樣做可以說(shuō)是非常簡(jiǎn)單, 但是這樣的硬編碼的, 基本上每個(gè)模塊每個(gè)功能, 你都必不可少的為其進(jìn)行重復(fù)的工作, 這是一項(xiàng)非常枯燥且無(wú)聊的體力活!
于是, 則考慮MVVM的架構(gòu)中, 如何把這種模式傳遞到ViewModel中, 使得前端的驗(yàn)證, 對(duì)于ViewModel仍然有效。
實(shí)現(xiàn)的原理, 如圖所示:
在此之前, 對(duì)于View前端驗(yàn)證需要做的一些操作步驟,
- 1.為驗(yàn)證的屬性添加自定義驗(yàn)證類
- 2.設(shè)置驗(yàn)證錯(cuò)誤的通知屬性 NotifyOnValidationError="True" 。 注: 如此一來(lái), 則可以產(chǎn)生Validation.ErrorEvent事件
- 3.通過(guò)自定義的 ValidationExceptionBehavior 繼承于 Behavior, 用于監(jiān)聽(tīng) Validation.ErrorEvent 的錯(cuò)誤事件。
- 4.在 ValidationExceptionBehavior 中通過(guò) AssociatedObjectde的DataContex獲取到關(guān)聯(lián)當(dāng)前View的DataContex, 從而改變DataContext的后端驗(yàn)證條件。
1.設(shè)置屬性自定義的驗(yàn)證類并添加 NotifyOnValidationError="True" 屬性
<TextBox Margin="15 0 10 0" Style="{StaticResource MaterialDesignFloatingHintTextBox}" materialDesign:HintAssist.Hint="登錄名 *"> <TextBox.Text> <Binding Path="Model.Account" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> <Binding.ValidationRules> <domain:CustomizeValidationRule validationType="Str" minLength="3" maxLength="10" errorMessage="輸入長(zhǎng)度范圍 [3-10]字" ValidatesOnTargetUpdated="True" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
2.自定義 IValidationExceptionHandler 接口, ViewModel繼承IValidationExceptionHandler , 用于接收前端的驗(yàn)證結(jié)果。
public interface IValidationExceptionHandler { /// <summary> /// 是否有效 /// </summary> bool IsValid { get; set; } }
3. 自定義 ValidationExceptionBehavior, 用于監(jiān)聽(tīng)處理View的錯(cuò)誤事件
/// <summary> /// 驗(yàn)證行為類,可以獲得附加到的對(duì)象 /// </summary> public class ValidationExceptionBehavior : Behavior<FrameworkElement> { /// <summary> /// 錯(cuò)誤計(jì)數(shù)器 /// </summary> private int _validationExceptionCount = 0; /// <summary> /// 附加對(duì)象時(shí) /// </summary> protected override void OnAttached() { //附加對(duì)象時(shí),給對(duì)象增加一個(gè)監(jiān)聽(tīng)驗(yàn)證錯(cuò)誤事件的能力,注意該事件是冒泡的 this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(this.OnValidationError)); } #region 獲取實(shí)現(xiàn)接口的對(duì)象 /// <summary> /// 獲取對(duì)象 /// </summary> /// <returns></returns> private IValidationExceptionHandler GetValidationExceptionHandler() { if (this.AssociatedObject.DataContext is IValidationExceptionHandler) { var handler = this.AssociatedObject.DataContext as IValidationExceptionHandler; return handler; } return null; } #endregion #region 驗(yàn)證事件方法 /// <summary> /// 驗(yàn)證事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnValidationError(object sender, ValidationErrorEventArgs e) { try { var handler = GetValidationExceptionHandler(); var element = e.OriginalSource as UIElement; if (handler == null || element == null) return; if (e.Action == ValidationErrorEventAction.Added) { _validationExceptionCount++; } else if (e.Action == ValidationErrorEventAction.Removed) { _validationExceptionCount--; } handler.IsValid = _validationExceptionCount == 0; } catch (Exception ex) { throw ex; } } #endregion }
4. View容器最外層注冊(cè)添加的監(jiān)聽(tīng)錯(cuò)誤事件 ValidationExceptionBehavior
<i:Interaction.Behaviors> <domain:ValidationExceptionBehavior></domain:ValidationExceptionBehavior> </i:Interaction.Behaviors>
5. ViewModel 通過(guò)實(shí)現(xiàn) IValidationExceptionHandler 來(lái)獲取前端的驗(yàn)證結(jié)果
根據(jù)前端驗(yàn)證的結(jié)果, 正確保存, 錯(cuò)誤進(jìn)行提示
public override void Save() { if (!this.IsValid) { MessageBox.Show("輸入的格式有誤,請(qǐng)重新輸入!"); return; } base.Save(); }
效果:
到此這篇關(guān)于WPF使用ValidationRules對(duì)MVVM架構(gòu)數(shù)據(jù)驗(yàn)證的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ASP.NET中 RadioButtonList 單選按鈕組控件的使用方法
本文主要簡(jiǎn)單介紹RadioButtonList控件的常見(jiàn)屬性和使用方法,希望對(duì)大家有所幫助。2016-04-04c#中實(shí)現(xiàn)文件拖放打開(kāi)的方法
向ListBox拖入一個(gè)文件,ListBox顯示該文件的路徑,然后單擊該路徑,點(diǎn)擊Open按鈕打開(kāi)該文件2006-10-10ASP.NET Core中的Options選項(xiàng)模式
這篇文章介紹了ASP.NET Core中的Options選項(xiàng)模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04SqlConnection.ConnectionString相關(guān)關(guān)鍵字
SqlConnection.ConnectionString相關(guān)關(guān)鍵字...2007-01-01.Net結(jié)構(gòu)型設(shè)計(jì)模式之代理模式(Proxy)
這篇文章介紹了.Net結(jié)構(gòu)型設(shè)計(jì)模式之代理模式(Proxy),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05ASP.NET?MVC模式中應(yīng)用程序結(jié)構(gòu)詳解
本文詳細(xì)講解了ASP.NET?MVC模式中的應(yīng)用程序結(jié)構(gòu),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03.Net創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)
這篇文章介紹了.Net設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Linux下使用Jenkins自動(dòng)化構(gòu)建.NET?Core應(yīng)用
這篇文章介紹了Linux下使用Jenkins自動(dòng)化構(gòu)建.NET?Core應(yīng)用的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04