我正在开发一个IDataErrorInfo
来验证我的应用程序中的文本框。我有以下代码:
要验证的.cs类:
public class UserInformation : IDataErrorInfo
{
public string _name;
public string _surname;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Surname
{
get { return _surname; }
set { _surname = value; }
}
public override string ToString()
{
return Name + " " + Surname;
}
public string this[string columnName]
{
get
{
if (columnName == null) return string.Empty;
string result = string.Empty;
if (columnName.Equals("Name"))
{
if (string.IsNullOrEmpty(_name))
result = "Name cannot be empty.";
}
return result;
}
}
public string Error { get; private set; }
}
.xaml:
<TextBox Grid.Column="3" Grid.Row="0" Name="TextBoxName"
Style="{DynamicResource InnerTextBox}"
Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}">
<TextBox.Text>
<Binding Path="Name" Source="{StaticResource UserInformation}"
ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
ErrorTemplate
:
<ControlTemplate x:Key="ValidationErrorTemplate">
<DockPanel >
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
<Grid Width="20" Height="20">
<Ellipse Width="20" Height="20" Fill="Tomato" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Foreground="White" FontWeight="Heavy" FontSize="8" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center"
ToolTip="{Binding ElementName=ErrorAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">X</TextBlock>
</Grid>
<TextBlock Foreground="Tomato" FontWeight="12" Margin="2,0,0,0" FontSize="20"
Text="{Binding ElementName=ErrorAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
</StackPanel>
<AdornedElementPlaceholder x:Name="ErrorAdorner" />
</DockPanel>
</ControlTemplate>
我打字时代码工作正常。但加载TextBox时,验证也会发生。我不希望它在获得焦点时发生,只有当它失去它或我改变文本时(就像在这里发布的那样)。
如何避免在第一次TextBox加载时考虑验证错误?
注意:即使我将UpdateSourceTrigger
设置为 LostFocus ,它仍然会进行验证。
答案 0 :(得分:3)
为了实现你的目标,你需要:
首先,删除绑定上的ValidatesOnDataErrors="True"
。如docs中所述:
设置此属性提供了使用该属性的替代方法 DataErrorValidationRule元素显式
我们会明确地使用它。然后使用DataErrorValidationRule
代替ExceptionValidationRule
正确使用IDataErrorInfo
和数据错误。
最后,我们需要使用此规则为我们提供的一些属性:
<Binding.ValidationRules>
<DataErrorValidationRule ValidatesOnTargetUpdated="False" />
</Binding.ValidationRules>
如果目标本身发生变化(即加载时),ValidatesOnTargetUpdated on false将不会触发验证。您还可以使用ValidationStep属性进行其他控制。
修改强>
好的,我发现您需要在加载和时跳过验证,即使值未更改,您也需要验证丢失的焦点。好吧,验证规则不支持这一点,因为如果值没有更新,那么无论UpdateSourceTrigger
设置如何,都不会调用更改的事件并且不会进行验证。
简单的方法是通过向TextBox本身添加LostFocus
处理程序来模拟此功能:
private void ValidatedTextBox_LostFocus(object sender, RoutedEventArgs e)
{
var txt = (TextBox)sender;
txt.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
如果您需要多个TextBox,则可以将代码移动到某个静态类。
使用Explicit update source trigger可以获得相同的结果,可以更清洁一些。
答案 1 :(得分:0)
我没有任何示例atm,因为我移动到你拥有的东西。但是您需要创建一个类,该类将继承自System.windows.controls中存在的ValidationRule,然后重写Validate方法。
然后你的xaml文本框看起来像这样
<TextBox.Text>
<Binding Path="your binding here" UpdateSourceTrigger="LostFocus" >
<Binding.ValidationRules>
<validationClass:yourRule/> define this at the top of xaml page
</Binding.ValidationRules>
</Binding>
您应该能够在msdn上找到示例,这里有关于验证规则的信息