【问题标题】:After validation a field, property has last valid value验证字段后,属性具有最后一个有效值
【发布时间】:2020-09-08 18:37:55
【问题描述】:

在我的 WPF 项目中,我开始使用带有文本字段的 ValidationRule 并发现了一个问题。我创建了一个简单的项目来测试 ValidationRule。一切正常,但如果我的输入值不在有效范围内,我的属性存储 last valid 值。这就是为什么我有一个问题:如何检查对 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;
        }
    }

【问题讨论】:

  • 不清楚你在问什么!请解释这个“我如何检查当前值,这对 ValidationRule 无效?”。您已添加 EmptyFieldRule,因此如果字段无效,则它必须具有空字符串或空格字符串。
  • 是的,你说得对。值应为空。例如:我插入texbox“5”,按下按钮并获得带有“5”的MessageBox。但是,当我删除“5”时,文本框变为空,ValidationRule 向我显示错误模板,我按下按钮,MessageBox 仍然有“5”。而且我不明白,为什么视图模型中的属性仍然包含'5'
  • 您是否期望验证规则允许用户输入无效数据?

标签: c# wpf xaml


【解决方案1】:

wpf 中的Binding 在更新值之前评估所有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;
    }
}

【讨论】:

  • 是的,我想过类似的事情,但不知道如何正确描述。这个方法对我有帮助。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 2016-06-09
  • 2016-11-09
  • 2019-12-23
  • 2018-10-16
  • 2014-10-08
  • 1970-01-01
相关资源
最近更新 更多