【问题标题】:WPF MVVM Textbox ValidationWPF MVVM 文本框验证
【发布时间】:2015-04-21 07:24:41
【问题描述】:

我正在使用 MVVM 创建 WPF 应用程序。我有一个文本框,它绑定到我的 ViewModel 中的 double 类型的属性,默认值为 0.0。如果我现在在文本框中输入文本值(例如 abc),则在失去焦点时,文本框会突出显示,表示值不正确。但是,用户仍然可以继续并单击提交以调用 ViewModel 命令。由于文本框的Text 属性绑定到ViewModel 中double 类型的属性,因此ViewModel 属性包含默认值0.0,我无法找出用户输入的文本。

因此,我无法确定用户是否实际输入了 0 值,或者是否存在错误输入。如何正确执行此验证?我是否应该将其绑定到 string 属性以便我可以获取输入的文本,并尝试将其解析为 double 值以查看输入是否正确?或者有更好的方法吗?

<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding DoubleProperty}" VerticalAlignment="Top" Width="120"/>

【问题讨论】:

  • 绑定到字符串属性的解决方案将始终有效。所以这取决于你:) 另外一种方式是创建某种行为,用户只能输入有效值(在你的情况下只是数字)

标签: c# .net wpf xaml mvvm


【解决方案1】:

您可以将验证规则附加到文本框的绑定中,以检查该值是否为有效的双精度值。这将阻止用户按下提交按钮,除非输入了有效值,从而无需在提交时检查 DoubleProperty 值是否有效,因为它仅在启用提交按钮时才有效。这是一个简单的例子:

<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
        <TextBox.Text>
            <Binding Path="DoubleProperty">
                <Binding.ValidationRules>
                    <validationrules:NumberValidationRule/>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

在上面的示例中,您需要定义一个继承 ValidationRule 的类 NumberValidationRule。

这是一个示例 NumberValidationRule

public class NumberValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        double result = 0.0;
        bool canConvert = double.TryParse(value as string, out result);
        return new ValidationResult(canConvert, "Not a valid double");
    }
}

添加验证规则后,如果您的 ValidationRule 类说它不是有效值,文本框将在文本字段上引发错误。

要防止启用提交按钮,您可以向其添加 CanExecute 事件,以检查 wpf 窗口是否有效。像这样:

<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Save" CanExecute="Save_CanExecute" Executed="Save_Executed"/>
</Window.CommandBindings>

... The rest of your page

<Button Content="Save" HorizontalAlignment="Left" Margin="43,146,0,0" VerticalAlignment="Top" Width="75" Command="ApplicationCommands.Save"/>                            

在后面的代码中

private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = IsValid(sender as DependencyObject);
    }

private bool IsValid(DependencyObject obj)
    {            
        return !Validation.GetHasError(obj) && LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>().All(IsValid);
    }

这里有一个更详细的例子:

Validation in WPF

【讨论】:

  • 验证规则有效,当文本框失去焦点时会引发错误。但是,按钮单击仍未禁用。我需要什么来防止“提交”按钮命令被触发?
  • 我在答案中添加了这些详细信息。
  • 我正在使用 MVVM,但无法阻止提交按钮触发。无论如何,我已将此标记为答案,我也在验证 VM 中的最终值,因此关于验证规则的答案的第一部分对我有用。谢谢。 :)
【解决方案2】:

您可以尝试以下解决方案。 首先,您应该将 DoubleProperty 声明为 Nullable

    public double? DoubleProperty { get; set; }

然后创建转换器类实现IValueConverter。它可以是这样的:

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double result;
        if(!double.TryParse((string)value, out result))
        {
            return null;
        }

        return result;
    }

终于可以使用了:

    xmlns:converter="clr-namespace:[TestApplication]"

<Window.Resources>
    <converter:DoubleToStringConverter x:Key="doubleToStringConverter" />
</Window.Resources>

<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding DoubleProperty, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource doubleToStringConverter}}" VerticalAlignment="Top" Width="120"/>

现在,如果用户输入了错误的值 - DoubleProperty 将为空。

【讨论】:

  • 谢谢,这会将属性重置为 null 并清除用户输入的无效文本。这解决了我识别用户输入是否有效的问题,但是,我希望保留以前的值并像以前一样突出显示文本框。我将尝试 ValidationRule 位,看看它是否更合适,是否像我想要的那样工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2014-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
相关资源
最近更新 更多