WPF DataGrid验证错误?

时间:2011-02-17 20:14:35

标签: c# .net wpf validation gridview

这可能是预期的功能,但对我来说肯定是个错误。

我正在使用开箱即用的WPF DataGrid,绑定到ObservableCollection并尝试使用一些验证规则以提供良好的用户反馈。毋庸置疑,有更多的问题比我可以计算的多,但我会坚持立即。

以下是问题摘要:

  1. ItemsSource属性绑定到ObservableCollection<T>
  2. 填充集合
  3. 以导致验证错误的方式编辑网格中的项目
  4. 以编程方式从ObservableCollection<T>
  5. 中删除该项目

    执行这些步骤后,GridView会正确识别该项目已从集合中删除,并从网格中删除该行。但是,网格现在处于无效状态,并且无法通过网格上的UI执行进一步的操作!

    同样,这似乎是一个很大的错误,因为能够以编程方式从集合中删除项目是一件大事。

    有没有人碰到这个?有关如何绕过它的任何建议吗?

    值得注意的是,我已经创建了一个单独的解决方案,只是为了解决这个问题,但回答了一些问题:

    您的对象是否实现了INotifyPropertyChanged

    这是一个自定义集合吗? 没有普通的ObservableCollection<T>

    如何从收藏中删除商品?

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

    您如何绑定验证规则?

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

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

    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;
        }
    }
    

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,经过漫长的搜索过程后,我找到了解决方案:

您可以创建一个派生自DataGrid的类。在那里,您可以通过反射访问私有财产。如果您现在删除了无效项,则可以调用函数SetGridWritable(),其他值可以再次编辑。

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);
    }
}

答案 1 :(得分:1)

我花了几个小时试图找出发生了什么。最后,对项目的简单刷新解决了这个问题。希望这会有所帮助。

YourDataGrid.Items.Refresh();

答案 2 :(得分:0)

如果您有兴趣,我有一个非解决方案:

我们发现整个验证机制充满了不必要的行为。 例如 - 我们希望允许用户输入无效数据,并仅标记错误。

为此,我们创建了一个带有红框的单元格模板,该框架与数据触发器绑定,只要给定属性的错误状态发生变化,就会调用该数据触发器。 datatrigger的实际创建是由依赖项属性完成的,该属性接收ViewModel属性的绑定路径并创建绑定

即:

DataTrigger errorTrigger = CreateTrigger(CreateDirectBinding(property,new HasErrorValueConverter()), CreateErrorSetter(property));

这解决了与验证错误相关的问题。