Wpf 验证错误时取消文本框输入
当输入字符串无效时,文本框中的标准行为是显示一个红方块(例如,用户在数字文本框中引入一个字母)。当文本框失去焦点时会发生这种情况 我希望实现此行为:Wpf 验证错误时取消文本框输入,wpf,validation,textbox,Wpf,Validation,Textbox,当输入字符串无效时,文本框中的标准行为是显示一个红方块(例如,用户在数字文本框中引入一个字母)。当文本框失去焦点时会发生这种情况 我希望实现此行为: 文本框失去焦点 文本框进行内部验证(日期、数字等) 若输入的用户字符串无效,则恢复旧值,TextBox不会显示任何错误 此链接中的文本框中有一个验证示例: ! 公共类NameValidator:ValidationRule { 公共覆盖验证结果验证 (对象值,System.Globalization.CultureInfo CultureInf
- 文本框失去焦点
- 文本框进行内部验证(日期、数字等)李>
- 若输入的用户字符串无效,则恢复旧值,TextBox不会显示任何错误
!
公共类NameValidator:ValidationRule
{
公共覆盖验证结果验证
(对象值,System.Globalization.CultureInfo CultureInfo)
{
如果(值==null)
返回新的ValidationResult(false,“值不能为空”);
其他的
{
if(value.ToString().Length>3)
返回新的ValidationResult
(false,“名称长度不能超过3个字符。”);
}
返回ValidationResult.ValidResult;
}
}
如果使用MVVM,恢复到旧值非常容易。在ViewModel的prop setter中,如果新值无效,则不能将其设置为模型,而是调用PropertyChanged
。这将告诉绑定视图元素调用属性getter,它将返回旧值,从而将视图元素的内容恢复为旧值
示例(验证用户输入是否为int
值):
这对于viewmodel中的验证非常有效。这里的问题是当用户引入无效的日期字符串,并且ViewModel中的属性是DateTime时。文本框本身进行内部验证并显示错误;textbox不会绑定到viewmodel,因为它无法将字符串转换为DateTime,并且错误的日期字符串仍保留在其中。
<ControlTemplate x:Key="validationErrorTemplate">
<DockPanel>
<TextBlock Foreground="Red"
DockPanel.Dock="Top">!</TextBlock>
<AdornedElementPlaceholder
x:Name="ErrorAdorner"
></AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
public class NameValidator : ValidationRule
{
public override ValidationResult Validate
(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
return new ValidationResult(false, "value cannot be empty.");
else
{
if (value.ToString().Length > 3)
return new ValidationResult
(false, "Name cannot be more than 3 characters long.");
}
return ValidationResult.ValidResult;
}
}
<TextBox Height="23" HorizontalAlignment="Left"
Grid.Column="1" Grid.Row="0" Name="textBox1"
VerticalAlignment="Top" Width="120"
Validation.ErrorTemplate="{StaticResource validationErrorTemplate}"
>
<TextBox.Text>
<Binding Path="Name" Mode="TwoWay"
UpdateSourceTrigger="LostFocus">
<Binding.ValidationRules>
<local:NameValidator></local:NameValidator>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
public string Number
{
get { return _model.Number.ToString(); }
set
{
if (_model.Number.ToString() != value)
{
int number;
if (int.TryParse(value, out number))
{
_model.Number = number;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Number));
}
}
}