WPF使用ValidationRules對MVVM架構(gòu)數(shù)據(jù)驗(yàn)證
對于WPF中的驗(yàn)證, View驗(yàn)證實(shí)現(xiàn)起來很簡單, 可以通道 Validation.ErrorEvent 冒泡傳遞到View的邏輯樹上, 只是, 通常這樣做的情況下, 我們需要為View添加事件代碼監(jiān)聽這類錯(cuò)誤事件, 然后進(jìn)行處理。
這樣做可以說是非常簡單, 但是這樣的硬編碼的, 基本上每個(gè)模塊每個(gè)功能, 你都必不可少的為其進(jìn)行重復(fù)的工作, 這是一項(xiàng)非??菰锴覠o聊的體力活!
于是, 則考慮MVVM的架構(gòu)中, 如何把這種模式傳遞到ViewModel中, 使得前端的驗(yàn)證, 對于ViewModel仍然有效。
實(shí)現(xiàn)的原理, 如圖所示:

在此之前, 對于View前端驗(yàn)證需要做的一些操作步驟,
- 1.為驗(yàn)證的屬性添加自定義驗(yàn)證類
- 2.設(shè)置驗(yàn)證錯(cuò)誤的通知屬性 NotifyOnValidationError="True" 。 注: 如此一來, 則可以產(chǎn)生Validation.ErrorEvent事件
- 3.通過自定義的 ValidationExceptionBehavior 繼承于 Behavior, 用于監(jiān)聽 Validation.ErrorEvent 的錯(cuò)誤事件。
- 4.在 ValidationExceptionBehavior 中通過 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="輸入長度范圍 [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)聽處理View的錯(cuò)誤事件
/// <summary>
/// 驗(yàn)證行為類,可以獲得附加到的對象
/// </summary>
public class ValidationExceptionBehavior : Behavior<FrameworkElement>
{
/// <summary>
/// 錯(cuò)誤計(jì)數(shù)器
/// </summary>
private int _validationExceptionCount = 0;
/// <summary>
/// 附加對象時(shí)
/// </summary>
protected override void OnAttached()
{
//附加對象時(shí),給對象增加一個(gè)監(jiān)聽驗(yàn)證錯(cuò)誤事件的能力,注意該事件是冒泡的
this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(this.OnValidationError));
}
#region 獲取實(shí)現(xiàn)接口的對象
/// <summary>
/// 獲取對象
/// </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容器最外層注冊添加的監(jiān)聽錯(cuò)誤事件 ValidationExceptionBehavior
<i:Interaction.Behaviors>
<domain:ValidationExceptionBehavior></domain:ValidationExceptionBehavior>
</i:Interaction.Behaviors>5. ViewModel 通過實(shí)現(xiàn) IValidationExceptionHandler 來獲取前端的驗(yàn)證結(jié)果
根據(jù)前端驗(yàn)證的結(jié)果, 正確保存, 錯(cuò)誤進(jìn)行提示
public override void Save()
{
if (!this.IsValid)
{
MessageBox.Show("輸入的格式有誤,請重新輸入!");
return;
}
base.Save();
}效果:

到此這篇關(guān)于WPF使用ValidationRules對MVVM架構(gòu)數(shù)據(jù)驗(yàn)證的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ASP.NET中 RadioButtonList 單選按鈕組控件的使用方法
本文主要簡單介紹RadioButtonList控件的常見屬性和使用方法,希望對大家有所幫助。2016-04-04
ASP.NET Core中的Options選項(xiàng)模式
這篇文章介紹了ASP.NET Core中的Options選項(xiàng)模式,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
SqlConnection.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),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
ASP.NET?MVC模式中應(yīng)用程序結(jié)構(gòu)詳解
本文詳細(xì)講解了ASP.NET?MVC模式中的應(yīng)用程序結(jié)構(gòu),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03
.Net創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)
這篇文章介紹了.Net設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
Linux下使用Jenkins自動(dòng)化構(gòu)建.NET?Core應(yīng)用
這篇文章介紹了Linux下使用Jenkins自動(dòng)化構(gòu)建.NET?Core應(yīng)用的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04

