简体   繁体   中英

WPF Datagrid Multiple Row Validation

Apologies if this question has already been asked, but I have not been able to find an answer to my specific problem.

I have a WPF datagrid which is bound to a Collection of objects called Waypoint that implements IDataErrorInfo . Each Waypoint object a set of properties that have DataItem which also implements IDataErrorInfo .

Each column in the datagrid is bound to the Value property of the DataItem object, and what I want is for the Waypoint object to be bound to the Row Validation template and the DataItem object to be bound to the Cell Validator.

I have a RowValidationRule as follows:

<DataGrid.RowValidationRules>
    <DataErrorValidationRule ValidationStep="UpdatedValue" ValidatesOnTargetUpdated="True"/>
</DataGrid.RowValidationRules>

I have got this partially working, but the row validation is only displayed when I navigate away from the row and more frustratingly if a row has an error then the validation rule is not executed on any subsequent rows, which is not what I want. I have tried looking at the code in the datagrid reference to see if I can do any overriding in the CommitEdit method to fire the validation rule, but I am stumped.

We have put in the override so that cells can be edited if the grid has any validation errors. As by default the grid isn't supposed to be editable until any errors have been cleared I am guessing that multiple row validation errors not being displayed is by design? If anyone has any ideas on how I could get round this it would be greatly appreciated!!!

For the second problem -

more frustratingly if a row has an error then the validation rule is not executed on any subsequent rows, which is not what I want

DataGrid does not actually commit the row if it has validation error. I found this piece of code in OnExecutedCommitEdit method in the Microsoft reference code-

if (validationPassed)
{
    CommitRowItem();
}

Which in turn does this-

private void CommitRowItem()
{
    if (IsEditingRowItem)
    {
        EditableItems.CommitEdit();
    }
    else
    {
        EditableItems.CommitNew();

        // Show the placeholder again
        UpdateNewItemPlaceholder(/* isAddingNewItem = */ false);
    }
}

To overcome this problem, I extended the DataGrid to make my own custom DataGrid and overrode OnExecutedCommitEdit as following -

protected override void OnExecutedCommitEdit(ExecutedRoutedEventArgs e)
{
    base.OnExecutedCommitEdit(e);
    BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance;
    PropertyInfo editableItems = this.GetType().BaseType.GetProperty("EditableItems", bindingFlags);
    ((System.ComponentModel.IEditableCollectionView)editableItems.GetValue(this)).CommitEdit();
}

This solution seems to work and I have not faced any issues till now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM