DataGrid: при ошибке проверки ячейки другие ячейки строки не редактируются / только для чтения
В моем wpf datagrid я реализовал проверку с использованием IDataErrorInfo
, При возникновении ошибки в ячейке ячейки в других строках становятся ReadOnly. Для меня это имеет смысл, но бизнес хочет иметь возможность изменять другие ячейки строки без исправления ошибки, то есть в некоторых сценариях пользователи могут создавать беспорядок и, бедная жизнь разработчика, быть несчастными.
Я попытался сбросить HasCellValidationError
ложно, но это не исправило это. Я буду очень признателен за любые отзывы / предложения по этому вопросу.
BindingFlags bf = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance;
PropertyInfo inf = myDataGrid.GetType().GetProperty("HasCellValidationError", bf);
if (inf != null)
{
inf.SetValue(myDataGrid, false, null);
}
1 ответ
Нашел решение путем переопределения метода OnCanExecuteBeginEdit сетки данных. См. Код ниже, и до сих пор тестеры не жаловались.
/// <summary>
/// This class overrides the OnCanExecuteBeginEdit method of the standard grid
/// </summary>
public partial class DataGrid : System.Windows.Controls.DataGrid
{
/// <summary>
/// This method overrides the
/// if (canExecute && HasRowValidationError) condition of the base method to allow
/// ----entering edit mode when there is a pending validation error
/// ---editing of other rows
/// </summary>
/// <param name="e"></param>
protected override void OnCanExecuteBeginEdit(System.Windows.Input.CanExecuteRoutedEventArgs e)
{
bool hasCellValidationError = false;
bool hasRowValidationError = false;
BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance;
//Current cell
PropertyInfo cellErrorInfo = this.GetType().BaseType.GetProperty("HasCellValidationError", bindingFlags);
//Grid level
PropertyInfo rowErrorInfo = this.GetType().BaseType.GetProperty("HasRowValidationError", bindingFlags);
if (cellErrorInfo != null) hasCellValidationError = (bool)cellErrorInfo.GetValue(this, null);
if (rowErrorInfo != null) hasRowValidationError = (bool)rowErrorInfo.GetValue(this, null);
base.OnCanExecuteBeginEdit(e);
if (!e.CanExecute && !hasCellValidationError && hasRowValidationError )
{
e.CanExecute = true;
e.Handled = true;
}
}
#region baseOnCanExecuteBeginEdit
//protected virtual void OnCanExecuteBeginEdit(CanExecuteRoutedEventArgs e)
//{
// bool canExecute = !IsReadOnly && (CurrentCellContainer != null) && !IsEditingCurrentCell && !IsCurrentCellReadOnly && !HasCellValidationError;
// if (canExecute && HasRowValidationError)
// {
// DataGridCell cellContainer = GetEventCellOrCurrentCell(e);
// if (cellContainer != null)
// {
// object rowItem = cellContainer.RowDataItem;
// // When there is a validation error, only allow editing on that row
// canExecute = IsAddingOrEditingRowItem(rowItem);
// }
// else
// {
// // Don't allow entering edit mode when there is a pending validation error
// canExecute = false;
// }
// }
// e.CanExecute = canExecute;
// e.Handled = true;
//}
#endregion baseOnCanExecuteBeginEdit
}
Gazi Ответ Gazi помогает сохранить редактируемую сетку. Однако, хотя с этой реализацией пользователи могут продолжать редактировать другие поля, значения этих дополнительных изменений не будут записаны в вашу модель, и дальнейшие проверки не могут быть выполнены. Проблема становится очевидной, когда дальнейшие изменения пользователя приведут к дополнительным ошибкам проверки. Они не будут возникать, потому что не произойдет обновления и проверки источника.
Чтобы преодолеть это, аналогичная реализация, как ваша, должна быть выполнена внутри OnExecutedCommitEdit
. См. Ответ на этот вопрос о проверке нескольких строк DataGrid