WPF DataGrid的验证错误?错误、WPF、DataGrid

2023-09-03 16:11:28 作者:安之若素つ

这可能是打算的功能,但它肯定似乎是一个错误给我。

我使用的是出的现成的WPF的DataGrid,势必一个ObservableCollection和的尝试的使用一些验证规则,以提供良好的用户反馈。不用说,还有更多的问题比我可以指望,但我会坚持使用即时的。

这是问题的一个总结:

绑定的ItemsSource 属性设置为一个的ObservableCollection< T> 填充集合 编辑网格的方式的项目,这将导致验证出错 从编程方式删除该项目的的ObservableCollection< T>

在执行这些步骤,在GridView正确识别该项目已被从集合中删除,并从电网中删除的行。然而,网格现在停留在一个无效的状态,并没有进一步的动作可以通过对电网的UI进行!

此外,这似乎挺喜欢一个重大的错误,以我为能够以编程方式从一个集合中删除的项目是怎么样的一个大问题。

有没有人遇到这个?对于任何建议如何解决呢?

值得一提的是,我创建了一个单独的解决方案,只是为了找出这个问题,但要回答一些问题,你可能有:

请问你的对象实施 INotifyPropertyChanged的?的是

这是一个自定义集合的否普通的老式的ObservableCollection< T>

你是如何去除你的藏品?的

  //查找任何新添加的项目,将其取下
VAR someObject = SomeObjects
             。凡(OBJ => obj.SomeProperty == someValue中)
             。第一();

SomeObjects.Remove(someObject);
 
WPF DATAGRID数据绑定问题

你是如何绑定您的验证规则?的

 < D​​ataGridTextColumn标题=SomeProperty>
    < D​​ataGridTextColumn.Binding>
        <绑定路径=SomeProperty>
            < Binding.ValidationRules>
                < VAL:RequiredValidator ValidationStep =ConvertedProposedValue
                     ValidatesOnTargetUpdated =真/>
            < /Binding.ValidationRules>
        < /装订>
    < /DataGridTextColumn.Binding>
< / DataGridTextColumn>
 

什么是您的验证规则什么样子的?的

 公共类RequiredValidator:有效性规则
{
    公众覆盖的ValidationResult验证(对象的值,System.Globalization.CultureInfo的CultureInfo)
    {
        如果(价值== NULL || String.IsNullOrWhiteSpace(值作为字符串))
            返回新的ValidationResult(假的,现场是必需的!);

        返回ValidationResult.ValidResult;
    }
}
 

解决方案

我有同样的问题,也是一个长期搜索过程后,我找到了一个解决办法:

您可以创建一个从DataGrid中派生的类。在那里,你可以通过反射访问私有属性。如果您现在删除无效的项目,你可以调用函数SetGridWritable()和其他值是可编辑的了。

 公共类MyDataGrid:数据网格
{
    公共无效SetGridWritable()
    {
        的BindingFlags的BindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic可| BindingFlags.Instance;
        。的PropertyInfo cellErrorInfo = this.GetType()BaseType.GetProperty(HasCellValidationError的BindingFlags);
        。的PropertyInfo rowErrorInfo = this.GetType()BaseType.GetProperty(HasRowValidationError的BindingFlags);
        cellErrorInfo.SetValue(本,假,空);
        rowErrorInfo.SetValue(本,假,空);
    }
}
 

This may be intended functionality, but it sure seems like a bug to me.

I'm using the out-of-the-box WPF DataGrid, bound to an ObservableCollection and attempting to use some validation rules in order to provide nice user feedback. Needless to say there are more issues than I can count, but I'll stick with the immediate.

Here is a summary of the problem:

Bind ItemsSource property to an ObservableCollection<T> Populate the collection Edit an item in the grid in a way which will cause a validation error Programatically remove that item from the ObservableCollection<T>

When these steps are performed, the GridView properly recognizes that the item has been removed from the collection, and removes the row from the grid. However, the Grid is now stuck in an invalid state and no further actions can be performed through the UI on the Grid!

Again, this seems quite like a major bug to me as being able to programmatically remove items from a collection is kind of a big deal.

Has anybody run into this? Any suggestions for how to get around it?

It is worth noting that I have created a separate solution just to isolate this problem, but to answers some questions you might have:

Does your object implement INotifyPropertyChanged? YES

Is this a custom collection? No plain old ObservableCollection<T>

How are you removing items from your collection?

//Find any newly added item and remove it  
var someObject = SomeObjects
             .Where(obj => obj.SomeProperty == SomeValue)
             .First();

SomeObjects.Remove(someObject );

How are you binding your validation rule?

<DataGridTextColumn Header="SomeProperty">
    <DataGridTextColumn.Binding>
        <Binding Path="SomeProperty">
            <Binding.ValidationRules>
                <val:RequiredValidator ValidationStep="ConvertedProposedValue" 
                     ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

What does your validation rule look like?

public class RequiredValidator : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        if (value == null || String.IsNullOrWhiteSpace(value as String))
            return new ValidationResult(false, "Field is required!");

        return ValidationResult.ValidResult;
    }
}

解决方案

I had the same problem and after a long search process I found a solution:

You can create a class which is derived from the DataGrid. There you can access the private properties by reflection. If you now remove an invalid item you can call the function SetGridWritable() and the other values are editable again.

public class MyDataGrid : DataGrid
{
    public void SetGridWritable()
    {
        BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance;
        PropertyInfo cellErrorInfo = this.GetType().BaseType.GetProperty("HasCellValidationError", bindingFlags);
        PropertyInfo rowErrorInfo = this.GetType().BaseType.GetProperty("HasRowValidationError", bindingFlags);
        cellErrorInfo.SetValue(this, false, null);
        rowErrorInfo.SetValue(this, false, null);
    }
}