c# - 验证字段后,属性具有最后一个有效值
问题描述
在我的 WPF 项目中,我开始使用带有文本字段的 ValidationRule 并发现了一个问题。我创建了一个简单的项目来测试 ValidationRule。一切正常,但如果我的输入值不在有效范围内,我的属性将存储最后一个有效值。这就是为什么我有一个问题:如何检查对ValidationRule无效的当前值?可能是,我做错了什么?
主窗口
</Window ... >
<Window.Resources>
<ControlTemplate x:Key="errorTemplate">
<Border BorderBrush="OrangeRed" BorderThickness="2">
<Grid>
<AdornedElementPlaceholder/>
<TextBlock Text="{Binding [0].ErrorContent}" Foreground="OrangeRed"
VerticalAlignment="Center" HorizontalAlignment="Right"
Margin="0,0,4,0"/>
</Grid>
</Border>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<TextBox Validation.ErrorTemplate ="{StaticResource errorTemplate}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="200" Margin="0 20">
<TextBox.Text>
<Binding Path="ForText"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:EmptyFieldRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Content="Check"
Command="{Binding ForCommand}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="40"/>
</StackPanel>
</Window>
我在 DataContext 中设置的 Window 视图模型:
public class MainWindowVM : VM
{
private string _text = "some text";
public string ForText
{
get => _text;
set { _text = value; OnPropertyChanged(nameof(ForText)); }
}
public ICommand ForCommand { get; set; }
public MainWindowVM() { ForCommand = new RelayCommand(() => MessageBox.Show(ForText)); }
}
验证规则:
public class EmptyFieldRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
string information = value as string;
if (string.IsNullOrWhiteSpace(information))
return new ValidationResult(false, "!!!");
return ValidationResult.ValidResult;
}
}
解决方案
Binding
在 wpf 中,ValidationRule
在更新值之前评估所有值。您必须在EmptyFieldRule
类中进行一些更改才能实现此目的。这是解决您的问题的一种技巧,但还有其他更好的方法来实现相同的。
ValidationStep
将属性更改为ValidationStep.UpdatedValue
并用于Reflection
获取ValidationResult
方法中的更新值。
public class EmptyFieldRule : ValidationRule
{
public EmptyFieldRule()
{
this.ValidationStep = ValidationStep.UpdatedValue;
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
var expression = value as BindingExpression;
var information = expression?.DataItem?.GetType()?.GetProperty(expression.ResolvedSourcePropertyName)?.GetValue(expression.DataItem) as string;
if (string.IsNullOrWhiteSpace(information))
return new ValidationResult(false, "!!!");
return ValidationResult.ValidResult;
}
}
推荐阅读
- excel - 将excel公式if/or语句添加到vba代码
- shader - 丢弃 ps_2_0 中的像素?
- nlp - 动词的子分类框架
- algorithm - 如何根据列表中的路径索引知道关卡的最后一个孩子
- azure - 在 azure cli 中运行多行语句
- php - 单击symfony 中的链接是否会提交表单?
- google-sheets - 如何在 googlesheet 中查找单元格可以有前导和尾随空格的项目数?
- flutter - Flutter pop 总是从上到下
- spring-boot - 如何在 Spring Cloud Gateway 中添加 Pre Filter
- javascript - 在 Javascript 中动态传递值并用作对象属性