所以我有一个WPF DataGrid,它必然会被绑定ObservableCollection.该集合通过对其成员进行验证IDataErrorInfo.如果我以某种方式编辑单元格以使其无效,然后在击中输入之前将其标记离开它,然后返回并使其有效,单元格将停止显示无效,但是,"!" 在行的头部仍将存在,并且ToolTip将引用先前的无效值.
我有一个这样的对象:
public class Person : IDataErrorInfo
{
public string PersonName{get;set;}
public int Age{get;set;}
string IDataErrorInfo.this[string propertyName]
{
get
{
if(propertyName=="PersonName")
{
if(PersonName.Length>30 || PersonName.Length<1)
{
return "Name is required and less than 30 characters.";
}
}
return null;
}
}
string IDataErrorInfo.Error
{
get
{
if(PersonName=="Tom" && Age!=30)
{
return "Tom must be 30.";
}
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
绑定PersonName和Age属性很简单:
<TextBox Text="{Binding PersonName, ValidatesOnDataErrors=True}" />
<TextBox Text="{Binding Age, ValidatesOnDataErrors=True}" />
Run Code Online (Sandbox Code Playgroud)
但是,如何使用Error属性并正确显示它?
我有两个日期字段:StartDate和EndDate.StartDate必须早于EndDate.
如果用户将StartDate更改为大于EndDate的值,则DatePicker周围会出现红色边框,反之亦然.如果用户更改第二个框以使日期范围现在正确,则第一个框仍然具有验证错误.
如果其中任何一个更改,我如何验证这两个日期字段?

我正在使用 IDataErrorInfo
public string GetValidationError(string propertyName)
{
switch (propertyName)
{
case "StartDate":
if (StartDate > EndDate)
s = "Start Date cannot be later than End Date";
break;
case "EndDate":
if (StartDate > EndDate)
s = "End Date cannot be earlier than Start Date";
break;
}
return s;
}
Run Code Online (Sandbox Code Playgroud)
我不能简单地引发一个PropertyChange事件,因为当它们中的任何一个发生变化时我需要验证这两个字段,因此让它们两个为另一个引发一个PropertyChange事件将陷入无限循环.
如果另一个日期返回验证错误,我也不喜欢清除Date字段的想法.
任何人都可以告诉我哪种方法更适合WPF中的验证.
在性能,内存泄漏,代码可维护性和重用方面.
我有一个基于MVVM的窗口,有许多控件,我的模型实现IDataErrorInfo.
还有一个SaveCommand按钮,通过分析Model.Error属性执行验证.
仅当我更改特定控件的值时,或者当我使用PropertyChanged通知有关该属性的更改时,视图才会显示控件周围的默认红色边框.
即使我没有触摸控件,如何强制View显示所有验证错误?
我的所有验证绑定都包括ValidatesOnDataErrors=True, NotifyOnValidationError=True.
我知道一个解决方案是有一个包含所有错误的聚合框,但我更愿意在每个控件的基础上显示错误.
我不想Model.NotifyPropertyChanged从ViewModel 触发每个绑定属性.
我使用的是WPF 4.0,而不是Silverlight,因此INotifyDataErrorInfo无法使用.
我正在尝试使用该IDataErrorInfo接口在我的WPF应用程序中实现验证,并且我遇到了一个不太理想的情况.
我有这个模板,当控件无法验证时使用
<ControlTemplate x:Key="errorTemplate">
<DockPanel LastChildFill="true">
<Border Background="Red" DockPanel.Dock="Right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" />
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
<Border BorderBrush="red" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
一切顺利,直到我尝试在验证失败的控件上方显示某些内容,例如在其上方显示停靠项:

如何避免这种情况并使我的错误模板显示在停靠项目下方,因为它应该如此?
编辑
我发现我可以TextBox用一个AdornerDecorator来修复它,但我真的不想为TextBox我的应用程序中的每个控件执行此操作.有没有办法用一种Style或其他方式设置它?
编辑2
我可能会更改默认的TextBoxControlTemplate以包含一个AdornerDecorator,但我不太热衷于更改任何WPF的默认控件模板.欢迎任何其他建议.
我在某个面板上有两个控件:textbox和combobox:
<TextBox Text="{Binding ShapeName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<ComboBox SelectedItem="{Binding ActiveStageViewModel, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
Run Code Online (Sandbox Code Playgroud)
当我在组合框上选择一些东西时,我需要强制对文本框进行idataerrorinfo验证.怎么做?
来自viewmodel的代码:
string IDataErrorInfo.this[string propertyName]
{
get
{
var error = string.Empty;
if (propertyName == Expression.GetPropertyName(() => ActiveStageViewModel))
{
// TODO: Add functionality to force ShapeName property validation
return error;
}
if (propertyName == Expression.GetPropertyName(() => ShapeName))
{
error = ValidateShapeName();
}
TooltipMessage = error;
return error;
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用IDataErrorInfo验证我的模型类,如下所示.
//Validators
public string this[string propertyName] {
get {
string error = null;
if (propertyName == "Name") {
error = ValidateName();
}
return error;
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但视图首次加载时已经包含验证错误.首次加载视图时是否可以忽略/禁止验证错误.此外,通常的做法是在视图加载时以及在用户启动模型属性的数据条目之前显示错误.
问候,Nirvan.
编辑: 这是我设置IDataErrorInfo的方式.
<TextBox Text="{Binding Name, ValidatesOnDataErrors=True}" Grid.Row="1" Grid.Column="1" />
Run Code Online (Sandbox Code Playgroud) 如果我的域对象实现了IDataErrorInfo,并且我使用的是MV-VM,那么如何通过ViewModel将错误传播到View?如果我直接绑定到模型,我会在绑定时将"ValidateOnExceptons"和"ValidateOnErrors"属性设置为true.但是我的ViewModel没有实现IDataErrorInfo.只有我的模特.我该怎么办?
澄清 我正在处理在域对象中实现IDataErrorInfo的现有代码库.我不能在我的视图模型中实现IDataErrorInfo.
我有一个TextBox实现的对象的属性绑定IDataErrorInfo.我成立Validation.ErrorTemplate的TextBox,并能正常工作.问题是我在a上有这些TabControl,如果我将标签更改为另一个标签然后返回到初始标签(其中TextBox),则验证模板不再显示.它看起来像是经过验证的(就像值是正确的),但实际上并非如此.
这是IDataErrorInfo对象 - 请注意,"正确"值是一个长度为2的字符串:
public class Presenter : IDataErrorInfo
{
public Presenter()
{
this.Property = String.Empty;
}
public string Property { get; set; }
public string Error { get { return null; } }
public string this[string columnName]
{
get
{
if (columnName == "Property")
{
if (this.Property.Length == 2)
return null;
else
return "Invalid property length!";
}
else return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是XAML:
<TabControl …Run Code Online (Sandbox Code Playgroud) idataerrorinfo ×10
wpf ×10
validation ×9
c# ×2
mvvm ×2
.net ×1
datagrid ×1
tabcontrol ×1
textbox ×1
wpf-4.0 ×1
wpfdatagrid ×1
xaml ×1