簡體   English   中英

如何捕獲PropertyChanged事件期間拋出的異常

[英]How to catch an exception thrown during a PropertyChanged event

我正在使用MVC \\ MVVM和WPF。 我有一個綁定到模型和控制器的表單,它捕獲PropertyChanged事件並評估業務規則和驗證。 好吧,我想在驗證錯誤時彈出一條消息告訴用戶有什么問題以及如何修復它。 但我不確定控制器的“正確”方式。 我想拋出一個可以被視圖捕獲的異常,但我無法弄清楚如何。 我已經嘗試過Dispatcher.Invoke(),但這只是在應用程序級別給我一個未處理的異常。

如何捕獲從Controller中的PropertyChanged事件處理程序生成的異常?

編輯:具體來說,我有一個組合框,里面有折扣列表。 我不能允許不恰當的選擇,但我必須通知用戶選擇不合適的原因。 這不像在其中包含整數的文本框那么明顯。 我需要告訴用戶客戶填寫調查的日期。 他們不能兩次使用該折扣。 我不想從列表中排除調查折扣,因為這對用戶來說只是一個錯誤。 我需要向他們展示折扣並告訴他們客戶已使用該折扣而不能再使用它。

編輯2:我查看了ValidationRule類,因為我必須使用數據庫查找,我不知道如何保留模型中的所有內容,並且仍然在Controller中有業務規則。 我看過IDataErrorInfo,但這要求我將我的模型包裝在我的Controller中並綁定到Controller,但僅限於一個字段。 我認為在這種情況下最好的做法是讓Controller在View上調用一個方法並彈出一條消息。

你走錯了路。

在MVVM中處理驗證的一種好方法是在綁定上實現IDataErrorInfo並將ValidatesOnDataErrors設置為true 您幾乎肯定也希望啟用ValidatesOnExceptions以獲得完整性,並且NotifyOnValidationError使綁定引擎在您綁定屬性的控件上觸發Validation.Error附加事件。

有關更多詳細信息,請參閱MSDN文檔中的驗證部分以獲取 WPF中的數據綁定

一些技巧:

  • .NET 4.5引入了INotifyDataErrorInfo和相應的ValidatesOnNotifyDataErrors綁定屬性,與IDataErrorInfo相比,它提供了增強的驗證功能。 你可能想調查一下。
  • 您不需要在IDataErrorInfo.Error實際執行任何有意義的操作,因為它由Windows Forms基礎結構使用並在WPF中被忽略。 你甚至可以讓getter拋出NotImplementedException
  • 有很好的閱讀材料說明了這種方法,並 這里這里完成了示例和代碼。

更新:澄清和示例代碼

此驗證模型不涉及自己實現ValidationRule ; 你的模型(即綁定源)只需要實現兩個接口中的一個。 如何實現界面完全取決於您; 在過去的項目中,我實現了基本的異步驗證

public interface IDelegatedValidation : IDataErrorInfo
{
    /// <summary>
    /// Occurs when validation is to be performed.
    /// </summary>
    event EventHandler<DelegatedValidationEventArgs> ValidationRequested;
}

public class DelegatedValidationEventArgs : EventArgs
{
    public DelegatedValidationEventArgs(string propertyName)
    {
        this.PropertyName = propertyName;
    }

    public string PropertyName { get; private set; }

    public bool Handled { get; set; }

    public string ValidationError { get; set; }
}

該模型通過公開事件和使用來實現IDelegatedValidation

string IDataErrorInfo.this[string columnName]
{
    get { return this.GetValidationError(columnName); }
}

private string GetValidationError(string propertyName)
{
    var args = new DelegatedValidationEventArgs(propertyName);
    this.OnValidationRequested(args);
    return args.ValidationError;
}

protected virtual void OnValidationRequested(DelegatedValidationEventArgs args)
{
    var handler = this.ValidationRequested;
    if (handler == null) {
        return;
    }

    foreach (EventHandler<DelegatedValidationEventArgs> target in handler.GetInvocationList()) {
        target.Invoke(this, args);
        if (args.Handled) {
            break;
        }
    }
}

所以工作流程如下:

  1. 當模型即將被視圖模型包裝時,一些可以執行驗證的適當實體會訂閱其ValidationRequested事件。
  2. 視圖綁定到模型; 在某些時候,驗證被觸發。
  3. 該模型調用GetValidationError
  4. 事件處理程序逐個調用; 產生驗證錯誤的第一個處理程序將args.ValidationErrorargs.Handledtrue以便鏈被停止。
  5. 驗證錯誤將返回到視圖。

如果視圖模型需要知道其模型是否有效(例如,啟用/禁用“保存”命令),還需要進入此過程。

IDataErrorInfo / INotifyDataErrorInfo實際上沒有什么可以做的,因為你如何實現它們完全取決於你。 對於更多示例,請務必查看后者文檔的Silverlight版本 ; 也有很多有用的材料, 這樣在互聯網上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM