2010-02-25 16 views
2

爲用戶可編輯字段創建自定義IValueConverter時,Convert實現通常相當簡單。值轉換期間的錯誤

的ConvertBack實現不是,因爲(在沒有明確的驗證規則),它必須應付惡意的用戶輸入(例如,在數字輸入字段中鍵入「HI」)。

如果在轉換過程中發生錯誤,似乎沒有被任何方式進行通信的特定的錯誤:

  • ConvertBack不允許拋出異常(如果這樣做,該程序終止)。
  • 返回ValidationError不會執行任何操作。
  • 返回DependencyProperty.UnsetValue(文檔建議)會導致無提示失敗(即使您設置了錯誤模板,也不會向用戶顯示錯誤UI)。
  • 返回原始未轉換值確實會導致顯示錯誤UI,但會顯示誤導性錯誤文本。

有誰知道有什麼更好的辦法來處理這樣的事情?

(注:在定義一個定製的有效性規則會的工作,我不認爲這是一個很好的答案,因爲它基本上是無論如何都要重複轉換邏輯來發現錯誤。)

回答

2

可避免重複通過讓驗證規則的第一步是調用值轉換器來確定它驗證的值是否可用,從而實現邏輯。

當然,這會將您的驗證規則結合到您的值轉換器,除非您制定驗證規則來搜索綁定以找出正在使用的值轉換器。但是如果你開始順着這條路走下去,那麼很快就會發生,就像它對很多人一樣,「等等,如果我使用MVVM,我在用價值轉換器搞什麼?」

編輯:

如果您的視圖模型實現IDataErrorInfo,這是真正的生活的唯一途徑,它是相對簡單掛鉤的值轉換成一個屬性setter無需編寫大量的特定屬性的驗證邏輯。

在你的ViewModel類,創建兩個私有字段:

Dictionary<string, string> Errors; 
Dictionary<string, IValueConverter>; 

創建他們(和填充第二)在構造函數中。此外,對於IDataErrorInfo

public string this[string columnName] 
{ 
    return Errors.ContainsKey(columnName) 
     ? Errors[columnName] 
     : null; 
} 

現在實現這樣的方法:

private bool ValidateProperty(string propertyName, Type targetType, object value) 
{ 
    Errors[propertyName] = null; 
    if (!Converters.ContainsKey(propertyName)) 
    { 
     return true; 
    } 
    try 
    { 
     object result = Converters[propertyName].ConvertBack(value, targetType, null, null) 
     return true; 
    } 
    catch (Exception e) 
    { 
     Errors[propertyName] = e.Message; 
     return false; 
    } 
} 

現在你的屬性設置如下:

public SomeType SomeProperty 
{ 
    set 
    { 
     if (ValidateProperty("SomeProperty", typeof(SomeType), value)) 
     { 
     _SomeProperty = value; 
     } 
    } 
} 
+0

我說的是一種情況,我不盡管如此,我們並不想定義一個驗證規則。 但是,是的,你是對的,你可以通過例如避免這個問題。將ViewModel中所有面向用戶的屬性定義爲字符串。但是,這似乎有點極端,並且*也*不能幫助顯示錯誤的用戶界面,至少不是內置的機制。 – Miral 2010-02-28 23:39:35

+0

避免這個問題?一點也不。看我的編輯。我概述的方法唯一的問題是能夠在綁定對象上設置值轉換器。如果您使用ViewModel,我無法想到將值轉換器附加到綁定的任何好理由。 – 2010-03-01 03:47:23