2013-04-12 4 views
3

У меня есть DataGrid, который я привязываю к ObservableCollection классов «Customer», реализуя IDataErrorInfo. Одним из свойств на классе Customer является int, и в моей реализации IDataErrorInfo проверить, что оно находится в пределах допустимого диапазона, e.g.:-Несоответствие валидации WPat datagrid

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 и в конечном итоге прибегал к тому, чтобы мои поддерживающие значения были строками. В окне вывода отладчика вы заметите, что исключение привязки или преобразования происходит, когда вы вводите альфа-символ в DataGridColumn, привязанный к int.

Вы можете получить другое поведение, изменив 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 заставляет значение, возвращаемое к текущему значению «модель».