这些代码有什么问题,Validation.Error永远不会被触发,而我将 NotifyOnValidationError 属性设置为 True 。因此,方法“Grid_Error(object sender,ValidationErrorEventArgs e)”永远不会被执行,但我不知道为什么:(
<Window xmlns:my="clr-namespace:WpfDigitalClock;assembly=WpfDigitalClock" x:Class="WpfApplication1.MainWindow"
xmlns:local="clr-namespace:WpfApplication1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:Names x:Key="MyNames" />
</Window.Resources>
<Grid Validation.Error="Grid_Error">
<TextBox Height="21" Margin="12,62,0,0" Name="TextBox1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120">
<TextBox.Text>
<Binding Source="{StaticResource MyNames}" Path="FirstName" NotifyOnValidationError="True">
<Binding.ValidationRules>
<local:StringValidator />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Height="21" HorizontalAlignment="Right" Margin="0,62,12,0" Name="TextBox2" VerticalAlignment="Top" Width="120" >
<TextBox.Text>
<Binding Source="{StaticResource MyNames}" Path="LastName" NotifyOnValidationError="True">
<Binding.ValidationRules>
<local:StringValidator />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button HorizontalAlignment="Left" Margin="35,122,0,116" Name="Button1" Width="75" Click="Button1_Click">Back</Button>
<Button HorizontalAlignment="Right" Margin="0,122,34,117" Name="Button2" Width="75" Click="Button2_Click">Forward</Button>
<Button Height="22" Margin="101,0,101,56" Name="Button3" VerticalAlignment="Bottom" Click="Button3_Click">Add</Button>
</Grid>
Window1.xaml.cs文件中的
:
public class StringValidator : ValidationRule
{
public override ValidationResult Validate(object value,
System.Globalization.CultureInfo cultureinfo)
{
string aString = value.ToString();
if (aString == "")
return new ValidationResult(false, "String cannot be null");
return new ValidationResult(true, null);
}
}
private void Grid_Error(object sender, ValidationErrorEventArgs e)
{
if(e.Action == ValidationErrorEventAction.Added)
MessageBox.Show(e.Error.ErrorContent.ToString());
}
感谢您的帮助!
编辑:
这是我的姓名类:
class Names : ObservableCollection<Name>
{
public Names ()
{
Name aName = new Name("FirstName " + (this.Count +1).ToString(),
"LastName " + (this.Count + 1).ToString());
this.Add(aName);
}
}
这是我的名字课:
class Name : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _firstName;
private string _lastName;
public Name(string fName, string lName)
{
_firstName = fName;
_lastName = lName;
}
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
}
}
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
PropertyChanged(this, new PropertyChangedEventArgs("LastName"));
}
}
}
答案 0 :(得分:3)
应用程序无法修改此集合的内容。有关如何使用此附加属性的示例,请参阅示例部分。
WPF数据绑定模型使您可以将ValidationRules与Binding对象相关联。在调用转换器之前,在绑定目标到绑定源值传输期间进行验证。以下描述了验证过程:
1.当值从目标属性传输到源属性时,数据绑定引擎首先删除可能已添加到绑定元素的Validation.Errors附加属性的任何ValidationError。然后它检查是否有为该Binding定义的任何自定义ValidationRules,在这种情况下,它会调用每个ValidationRules上的Validate方法,直到其中一个遇到错误或直到所有这些都通过。
2.一旦有自定义规则未通过,绑定引擎就会创建一个ValidationError对象并将其添加到绑定元素的Validation.Errors集合中。当Validation.Errors不为空时,元素的Validation.HasError附加属性设置为true。此外,如果Binding的NotifyOnValidationError属性设置为true,则绑定引擎会在元素上引发Validation.Error附加事件。
3.如果所有规则都通过,绑定引擎会调用转换器(如果存在)。
4.如果转换器通过,绑定引擎将调用source属性的setter。
5.如果绑定具有与之关联的ExceptionValidationRule,则在步骤期间抛出异常 4,绑定引擎检查是否有UpdateSourceExceptionFilter。您可以选择使用UpdateSourceExceptionFilter回调来提供处理异常的自定义处理程序。如果未在Binding上指定UpdateSourceExceptionFilter,则绑定引擎会创建带有异常的ValidationError,并将其添加到绑定元素的Validation.Errors集合中。
另请注意,在任一方向(目标到源或源到目标)的有效值传输都会清除Validation.Errors附加属性。
有关MultiBinding方案中此属性的行为的信息,请参阅ValidationError。
答案 1 :(得分:2)
根据您的评论,我会得出结论ValidationRule不会返回错误,因此不会触发错误事件。尝试使用调试器逐步执行Validation方法。
此外,验证仅在通常在LostFocus
上发生的TextBox中的源更新时执行。
编辑: MyNames
是一个集合,它没有您尝试绑定的属性,“输出”窗口中应该存在绑定错误。
如果要绑定到第一个元素,则需要将路径更改为类似[0].LastName
的内容,以用于姓氏绑定。
答案 2 :(得分:0)
你的Names类是否实现了INotifyPropertyChanged?
在文件的代码隐藏文件中,将datacontext设置为this
。将您的Names
对象公开为属性,看看是否有效。我不习惯绑定到窗口中的静态资源。