2013-04-12 52 views
3

我有一個DataGrid綁定到「Customer」類的ObservableCollection,實現了IDataErrorInfo。一個Customer類的屬性是int,在我IDataErrorInfo的執行我檢查,這是一個有效的範圍內,e.g.:-WPF數據網格驗證不一致性

public class Customer : IDataErrorInfo 
{ 
    public int PercentDiscount { get; set; } 

    ... other properties & methods removed for clarity 

    public string this[columnName] 
    { 
     get 
     { 
      if (PercentDiscount < 0 || PercentDiscount > 10) 
       return "Percent Discount is invalid"; 
     } 
    } 
} 

在我的XAML我的代碼隱藏處理幾個事件。在PreparingCellForEdit事件中,我存儲對行的引用被編輯: -

private void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e) 
{ 
    _rowBeingEdited = e.Row; 
} 

然後在RowEditEnding事件中,我採取了一些行動,如果該行處於無效狀態(在我的情況我回復客戶屬性恢復他們以前的「好」的值): -

private void DataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) 
{ 
    if (_rowBeingEdited != null) 
    { 
     var errors = Validation.GetErrors(_rowBeingEdited); 
     if (errors.Count > 0) 
     { 
      .. do something 
     } 
    } 
} 

這工作正常,如果用戶輸入失敗我的驗證規則的數值,但如果用戶輸入一個非數字值,那麼RowEditEnding事件從未火災該單元保持編輯狀態。我認爲這是因爲WPF無法將非數字值綁定到int屬性。有什麼辦法可以檢測/處理這種情況嗎?

最後的手段是將PercentDiscount屬性更改爲字符串,但我試圖避免沿着這條路線走下去。

編輯 - 我剛剛發現,我可以用CellEditEnding事件,而不是RowEditEnding成功地處理這兩種類型的錯誤。雖然出現了一個新問題 - 如果我輸入一個無效值到單元格中,然後按輸入,底層屬性不會更新,因此當CellEditEnding觸發Validation.GetErrors爲空時。最終的結果是該行離開編輯模式,但仍在紅色邊框的單元格中顯示無效值。任何想法現在發生了什麼?

回答

1

這可能不是一個很大的答案,尤其是因爲你已經提到它,但我已經爭取了一段時間DataGrid驗證,並最終訴諸使我的支持值爲字符串。您會注意到在調試器的輸出窗口中,當您將一個字母字符輸入綁定到一個int的DataGridColumn時,會發生綁定或轉換異常。

您可以通過更改UpdateSourceTrigger或將轉換器放在綁定和屬性之間來獲得不同的行爲,但我從未得到我需要的東西,直到我用字符串支持這些值爲止。

我想你也可以嘗試創建自己的DataGridNumericColumn派生自DataGridTextColumn,也許你會有更多的控制綁定/驗證行爲。

1

我掙扎着找到一個很好的解決辦法,但我看到一些人用CellEditEnding事件搞亂我結束了,想出這個代碼,如果他們不轉換恢復值:

private void CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    if (e.EditingElement is TextBox) 
    { 
     var cellTextBox = (TextBox)e.EditingElement; 
     var cellTextBoxBinding = cellTextBox.GetBindingExpression(TextBox.TextProperty); 
     if (cellTextBoxBinding != null && !cellTextBoxBinding.ValidateWithoutUpdate()) 
     { 
      cellTextBoxBinding.UpdateTarget(); 
     } 
    } 
} 

在編輯元素綁定上調用ValidateWithoutUpdate將返回false,如果該值的轉換失敗,則調用UpdateTarget將強制將值恢復爲當前的「模型」值。