WPF MVVM 文本框验证
WPF MVVM Textbox Validation
我正在使用 MVVM 创建 WPF 应用程序。我有一个文本框,它绑定到我的 double
类型的 ViewModel 中的 属性,默认值为 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"/>
您可以将验证规则附加到文本框的绑定,以检查该值是否为有效的双精度值。这将阻止用户在输入有效值之前无法按下提交按钮,从而无需在提交时检查 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的classNumberValidationRule。
这是一个示例 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 class 表明其不是有效值,文本框将在文本字段上引发错误。
要防止启用提交按钮,您可以向其中添加一个 CanExecute 事件来检查 wpf window 是否有效。像这样:
<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);
}
这里有一个更详细的例子:
您可以尝试以下解决方案。
首先你应该声明 DoubleProperty 为 Nullable:
public double? DoubleProperty { get; set; }
然后创建转换器 class 实现 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 将为空。
我正在使用 MVVM 创建 WPF 应用程序。我有一个文本框,它绑定到我的 double
类型的 ViewModel 中的 属性,默认值为 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"/>
您可以将验证规则附加到文本框的绑定,以检查该值是否为有效的双精度值。这将阻止用户在输入有效值之前无法按下提交按钮,从而无需在提交时检查 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的classNumberValidationRule。
这是一个示例 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 class 表明其不是有效值,文本框将在文本字段上引发错误。
要防止启用提交按钮,您可以向其中添加一个 CanExecute 事件来检查 wpf window 是否有效。像这样:
<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);
}
这里有一个更详细的例子:
您可以尝试以下解决方案。 首先你应该声明 DoubleProperty 为 Nullable:
public double? DoubleProperty { get; set; }
然后创建转换器 class 实现 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 将为空。