简体   繁体   中英

wpf Datagrid force datagrid row evaluation

I have a DataGridView that with a row validation property:

<DataGrid ItemsSource="{Binding SetupXml.Files.FileList}">
    <DataGrid.RowValidationRules>
        <vm:FileServerValidation ValidationStep="CommittedValue"/>
    </DataGrid.RowValidationRules>
</DataGrid>

Whenever the User changes a value in the DataGridView (and commits it) my ValidationRule is called:

public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
    if (!(value is BindingGroup bg))
        return ValidationResult.ValidResult;
    foreach (var item in bg.Items)
    {
        if (!(item is FileServer c))
            continue;

        if (string.IsNullOrWhiteSpace(c.FileServerName))
            return new ValidationResult(false, "File server name is empty");

        if (c.FileServerName.Length < 3)
            return new ValidationResult(false, "File server name is to short");
    }

    return ValidationResult.ValidResult;
}

Due to various reasons I would like to trigger a complete validation of the grid whenever the user clicks a submit button.

Therefore I wrote a function that gets the ErrorStatus of all DataGridRows.

public static bool HasInvalidRows(DataGrid datagrid)
{
    var valid = true;
    foreach (var item in datagrid.ItemContainerGenerator.Items)
    {
        var evaluateItem = datagrid.ItemContainerGenerator.ContainerFromItem(item);
        if (evaluateItem == null) continue;

        valid &= !System.Windows.Controls.Validation.GetHasError(evaluateItem);
    }

    return !valid;
}

The problem is: the ValidationRule is not called for every row but only for those rows that were changed. This way if some of the data in a row was inserted through a master detail section, some rows might not have been evaluated and the Validation.GetHasError will return a not evaluated result which defaults to true.

Do you have any idea how to accomplish that?

I found my own answer now:

Each DataGridRow has a BindingGroup . Further information on can be found here .

Whenever the BindingGroup.CommitEdit() is called, the validation executes.

Note that I have set the ValidationStep to CommittedValue in the xaml row validation Tag.

public static bool HasInvalidRows(DataGrid datagrid)
{
    var valid = true;
    foreach (var item in datagrid.ItemContainerGenerator.Items)
    {
        var evaluateItem = datagrid.ItemContainerGenerator.ContainerFromItem(item);
        if (evaluateItem == null) continue;

        if (!(evaluateItem is DataGridRow dgr)) continue;

        dgr.BindingGroup.CommitEdit();

        valid &= !System.Windows.Controls.Validation.GetHasError(evaluateItem);
    }

    return !valid;
}

I hope it helps.

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