开发者

DataGrid: On cell validation error other row cells are uneditable/Readonly

开发者 https://www.devze.com 2023-01-23 04:45 出处:网络
In my wpf datagrid I have implemented validation using IDataErrorInfo. When there is a error in a cell, cells in other rows become ReadOnly. To me this makes sense, but business wants to be able to ch

In my wpf datagrid I have implemented validation using IDataErrorInfo. When there is a error in a cell, cells in other rows become ReadOnly. To me this makes sense, but business wants to be able to change other row cells without fixing the error i.e. in some scenarios let users make a mess and, poor developer's life miserable.

I have tried resetting HasCellValidationError to false but it did not fix it. I'll very highly appreciate any feedback/suggestion on this issue.

BindingFlags bf = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | Bin开发者_StackOverflow社区dingFlags.Instance;
PropertyInfo inf = myDataGrid.GetType().GetProperty("HasCellValidationError", bf);

if (inf != null)
{
    inf.SetValue(myDataGrid, false, null);
}


Found a solution by overriding the OnCanExecuteBeginEdit method of the datagrid. See the code below and so far testers have not complaint.

/// <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's answer does the trick with regards to keeping the grid editable. However, while with this implementation users can continue to edit other fields, the values of these additional changes will not be written to your model and no further validations can be done. The problem becomes apparent when further user changes would result in additional Validation Errors. These will not be raised, because source update and validation won't happen.

To overcome this a similar implementation like yours needs to be done inside OnExecutedCommitEdit. See the answer to this multiple DataGrid row validation question

0

精彩评论

暂无评论...
验证码 换一张
取 消