wpf Datagrid强制datagrid行评估 [英] wpf Datagrid force datagrid row evaluation

查看:73
本文介绍了wpf Datagrid强制datagrid行评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有行验证属性的 DataGridView :

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

每当用户更改(并提交)DataGridView中的值时,我的 ValidationRule 就会被称为:

 公共重写ValidationResult Validate(对象值,CultureInfo cultureInfo){如果(!(值为BindingGroup bg))返回ValidationResult.ValidResult;foreach(bg.Items中的可变项){如果(!(项目是FileServer c))继续;如果(string.IsNullOrWhiteSpace(c.FileServerName))返回新的ValidationResult(false,文件服务器名称为空");如果(c.FileServerName.Length< 3)返回新的ValidationResult(false,文件服务器名称短");}返回ValidationResult.ValidResult;} 

由于各种原因,每当用户单击提交按钮时,我都希望触发对网格的完全验证.

因此,我编写了一个函数,该函数获取所有DataGridRows的 ErrorStatus .

 公共静态布尔HasInvalidRows(DataGrid datagrid){var valid = true;foreach(datagrid.ItemContainerGenerator.Items中的可变项){var EvaluationItem = datagrid.ItemContainerGenerator.ContainerFromItem(item);如果(evaluateItem == null)继续;有效& =!System.Windows.Controls.Validation.GetHasError(evaluateItem);}返回!valid;} 

问题是:不是为每一行都调用ValidationRule,而是仅为已更改的那些行调用.这样,如果通过主详细信息部分插入了一行中的某些数据,则可能未对某些行进行求值,并且 Validation.GetHasError 将返回未求值的结果,默认为true.

您知道如何实现吗?

解决方案

我现在找到了自己的答案:

每个 DataGridRow 都有一个 BindingGroup .有关更多信息,请参见这里.

每当调用 BindingGroup.CommitEdit()时,都会执行验证.

请注意,我已经在xaml行验证标签中将 ValidationStep 设置为 CommittedValue .

 公共静态布尔值HasInvalidRows(DataGrid datagrid){var valid = true;foreach(datagrid.ItemContainerGenerator.Items中的可变项){var EvaluationItem = datagrid.ItemContainerGenerator.ContainerFromItem(item);如果(evaluateItem == null)继续;如果(!(evaluateItem是DataGridRow dgr))继续;dgr.BindingGroup.CommitEdit();有效& =!System.Windows.Controls.Validation.GetHasError(evaluateItem);}返回!valid;} 

希望对您有帮助.

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.

这篇关于wpf Datagrid强制datagrid行评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆