C# WPF数据网格和绑定到行数据上下文

C# WPF数据网格和绑定到行数据上下文,c#,wpf,datagrid,C#,Wpf,Datagrid,我们研究了在wpf datagrid中使用开箱即用的验证,但发现它没有给我们足够的控制权来控制验证的工作方式。也就是说,在用户单击“保存”按钮或编辑该字段之前,我们不希望该字段显示为无效。我们能够使用textbox和checkbox来实现这一点,并提供了一个我们满意的解决方案。我们相信只要我们能够访问一行绑定到的对象,它就可以用于datagrdi。但是,我们无法通过绑定获得对象 我已经附加了代码的相关部分来复制示例。ValidationContext类上的ObjectToValidate属性是我

我们研究了在wpf datagrid中使用开箱即用的验证,但发现它没有给我们足够的控制权来控制验证的工作方式。也就是说,在用户单击“保存”按钮或编辑该字段之前,我们不希望该字段显示为无效。我们能够使用textbox和checkbox来实现这一点,并提供了一个我们满意的解决方案。我们相信只要我们能够访问一行绑定到的对象,它就可以用于datagrdi。但是,我们无法通过绑定获得对象

我已经附加了代码的相关部分来复制示例。ValidationContext类上的ObjectToValidate属性是我们想要绑定row对象的对象。如果要连接下面的代码,请运行它,然后编辑“名称”列中的一个单元格,您将在PropertyValidation类的ValidateMethod中获得异常

窗口XAML

<Window x:Class="DataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow">
    <DataGrid ItemsSource="{Binding MyItems}" IsReadOnly="{Binding IsReadOnly}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name">
                <DataGridTextColumn.Binding>
                    <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                        <Binding.ValidationRules>
                            <behaviors:PropertyValidation PropertyName="Name">
                                <behaviors:PropertyValidation.Context>
                                    <behaviors:ValidationContext ObjectToValidate="{Binding}"/>
                                </behaviors:PropertyValidation.Context>
                            </behaviors:PropertyValidation>
                        </Binding.ValidationRules>
                    </Binding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>
ValidationContext类

public class ValidationContext : DependencyObject
{

    public object ObjectToValidate
    {
        get { return (object)GetValue(ObjectToValidateProperty); }
        set { SetValue(ObjectToValidateProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ObjectToValidate.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ObjectToValidateProperty =
        DependencyProperty.Register("ObjectToValidate", typeof(object), typeof(ValidationContext), new PropertyMetadata(null));
}

很难找到这个,但它只是绑定:

<behaviors:ValidationContext ObjectToValidate="{Binding}"/>
然后XAML将如下所示:

<DataGrid ItemsSource="{Binding MyItems}" IsReadOnly="{Binding IsReadOnly}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name">
                <DataGridTextColumn.Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
                    <DataGridTextColumn.Binding.ValidationRules>
                        <DataErrorValidationRule/>
                   </DataGridTextColumn.Binding.ValidationRules>
               </DataGridTextColumn.Binding>
            </DataGridTextColumn>
          </DataGrid.Columns>
 </DataGrid>


您到底遇到了什么问题?我们在使用开箱即用验证时遇到了问题,因为字段在我们准备好验证之前就会验证。我们已经修复了除网格以外的所有问题。它还让我们能够更精确地控制验证的时间和方式。将它绑定到网格中是我们剩下的唯一一件事,如果我可以访问该行绑定到的对象,那么在这种情况下我们就可以了。我试图解决同样的问题,最终得到了一个非常类似的解决方案。问题是当调用
Validate
时,与我的代码等价的
上下文总是
null
。我该如何解决这个问题?你让它工作了吗?谢谢你的回复,乔希,但这对我来说仍然不起作用。对象仍返回为空。今天我将尝试发布更多的代码。我已经更新了我的代码示例,以包含所有必要的部分。
<behaviors:ValidationContext ObjectToValidate="{Binding}"/>
public class MyItem : IDataErrorInfo
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public string Error
        {
            get
            {
                return null;
            }
        }

        public string this[string name]
        {
            get
            {
                string result = null;

                if (name == "Name")
                {
                    if (string.IsNullOrEmpty(Name))
                    {
                        result = "Name must be specified.";
                    }
                }
                return result;
            }
        }
    }
<DataGrid ItemsSource="{Binding MyItems}" IsReadOnly="{Binding IsReadOnly}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name">
                <DataGridTextColumn.Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
                    <DataGridTextColumn.Binding.ValidationRules>
                        <DataErrorValidationRule/>
                   </DataGridTextColumn.Binding.ValidationRules>
               </DataGridTextColumn.Binding>
            </DataGridTextColumn>
          </DataGrid.Columns>
 </DataGrid>