網站首頁 編程語言 正文
對于WPF中的驗證, View驗證實現起來很簡單, 可以通道 Validation.ErrorEvent 冒泡傳遞到View的邏輯樹上, 只是, 通常這樣做的情況下, 我們需要為View添加事件代碼監聽這類錯誤事件, 然后進行處理。
這樣做可以說是非常簡單, 但是這樣的硬編碼的, 基本上每個模塊每個功能, 你都必不可少的為其進行重復的工作, 這是一項非常枯燥且無聊的體力活!
于是, 則考慮MVVM的架構中, 如何把這種模式傳遞到ViewModel中, 使得前端的驗證, 對于ViewModel仍然有效。
實現的原理, 如圖所示:
在此之前, 對于View前端驗證需要做的一些操作步驟,
- 1.為驗證的屬性添加自定義驗證類
- 2.設置驗證錯誤的通知屬性 NotifyOnValidationError="True" 。 注: 如此一來, 則可以產生Validation.ErrorEvent事件
- 3.通過自定義的 ValidationExceptionBehavior 繼承于 Behavior, 用于監聽 Validation.ErrorEvent 的錯誤事件。
- 4.在 ValidationExceptionBehavior 中通過 AssociatedObjectde的DataContex獲取到關聯當前View的DataContex, 從而改變DataContext的后端驗證條件。
1.設置屬性自定義的驗證類并添加 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 , 用于接收前端的驗證結果。
public interface IValidationExceptionHandler { /// <summary> /// 是否有效 /// </summary> bool IsValid { get; set; } }
3. 自定義 ValidationExceptionBehavior, 用于監聽處理View的錯誤事件
/// <summary> /// 驗證行為類,可以獲得附加到的對象 /// </summary> public class ValidationExceptionBehavior : Behavior<FrameworkElement> { /// <summary> /// 錯誤計數器 /// </summary> private int _validationExceptionCount = 0; /// <summary> /// 附加對象時 /// </summary> protected override void OnAttached() { //附加對象時,給對象增加一個監聽驗證錯誤事件的能力,注意該事件是冒泡的 this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(this.OnValidationError)); } #region 獲取實現接口的對象 /// <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 驗證事件方法 /// <summary> /// 驗證事件 /// </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容器最外層注冊添加的監聽錯誤事件 ValidationExceptionBehavior
<i:Interaction.Behaviors> <domain:ValidationExceptionBehavior></domain:ValidationExceptionBehavior> </i:Interaction.Behaviors>
5. ViewModel 通過實現 IValidationExceptionHandler 來獲取前端的驗證結果
根據前端驗證的結果, 正確保存, 錯誤進行提示
public override void Save() { if (!this.IsValid) { MessageBox.Show("輸入的格式有誤,請重新輸入!"); return; } base.Save(); }
效果:
原文鏈接:https://www.cnblogs.com/zh7791/p/11432827.html
相關推薦
- 2022-10-04 Redis中Redisson紅鎖(Redlock)使用原理_Redis
- 2022-02-19 DevTools 無法加載 SourceMap 錯誤:狀態代碼 404,net::ERR_HTTP_
- 2022-03-24 redis如何設置key的有效期_Redis
- 2022-05-26 C++?棧和隊列的實現超詳細解析_C 語言
- 2023-03-22 Linux?rm命令詳解?Linux刪除文件目錄的操作方法_linux shell
- 2023-04-06 C++聚合體初始化aggregate?initialization詳細介紹_C 語言
- 2022-07-04 解決Python保存文件名太長OSError:?[Errno?36]?File?name?too?l
- 2022-07-09 Python實現功能全面的學生管理系統_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支