我们研究了使用wpf datagrid的开箱即用验证,但发现它没有给我们足够的控制验证的工作方式。即,在用户单击“保存”按钮或编辑该字段之前,我们不希望字段显示为无效。我们能够通过文本框和复选框使用我们满意的解决方案。我们相信它只适用于datagrdi,只要我们可以访问行绑定的对象。但是,我们无法通过绑定来获取对象。
我已附上代码的相关部分以重现样本。 ValidationContext类上的ObjectToValidate属性是我们想要将行对象绑定到的属性。如果你连线下面的代码运行它,然后编辑Name列中的一个单元格,你将在PropertyValidation类的ValidateMethod中获得异常。
Window 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>
Windows代码背后
public partial class MainWindow : Window
{
public ObservableCollection<MyItem> MyItems { get; set; }
public MainWindow()
{
InitializeMyItems();
InitializeComponent();
DataContext = this;
}
private void InitializeMyItems()
{
MyItems = new ObservableCollection<MyItem>();
for (int i = 0; i < 10; i++)
{
MyItems.Add(new MyItem() { Age = i, Name = "Name" + i.ToString() });
}
}
}
PropertyValidation Class
public class PropertyValidation : ValidationRule
{
public string PropertyName { get; set; }
public ValidationContext Context { get; set; }
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (Context.ObjectToValidate == null) throw new Exception("The validation object is null.");
return new ValidationResult(true, "");
}
}
ValidationContext Class
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));
}
答案 0 :(得分:0)
很难找到这个,但它只是绑定:
<behaviors:ValidationContext ObjectToValidate="{Binding}"/>
{Binding}通常表示在某一行绑定的对象。
修改强>
您可以在MyItem类上使用IDataErrorInfo接口吗?
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;
}
}
}
然后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>