WPF MVVM Textbox Validation

天涯浪子 提交于 2020-06-09 18:19:16

问题


I'm creating a WPF application using MVVM. I have a textbox, which is bound to a property in my ViewModel of type double with a default value of 0.0. If I now enter a text value (say, abc) in the textbox, upon losing focus, the textbox is highlighted indicating an incorrect value. However, the user can still go ahead and click on Submit to invoke a ViewModel command. As the Text property of the textbox is bound to a property of type double in the ViewModel, the ViewModel property contains the default value, 0.0, and I'm unable to find out the text entered by the user.

Therefore, I'm unable to figure out if the user has actually entered a value of 0 or if there has been an incorrect input. How can I perform this validation correctly? Should I bind it to a string property so that I can get the entered text, and try to parse it to a double value to see if the input is correct? Or is there a better way of doing this?

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

回答1:


You can attach a Validation Rule to the binding of the textbox that checks if the value is a valid double. This will prevent the user from being able to press the Submit button unless a valid value is entered thereby eliminating your need to check if the DoubleProperty value is valid or not upon submit because it will only be valid when the submit button is enabled. Here is a simple example:

<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>

In the above example you need to define a class NumberValidationRule that inherits ValidationRule.

Here is a sample 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");
    }
}

Once you add a validation rule the text box will raise an error on the text field if your ValidationRule class says its not a valid value.

To prevent the submit button from being enabled you can add a CanExecute event to it that checks if the wpf window is valid. Like so:

<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"/>                            

and in the code behind

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);
    }

Here is a more detailed example:

Validation in WPF




回答2:


You can try following solution. Firstly you should declare DoubleProperty as Nullable:

    public double? DoubleProperty { get; set; }

Then create converter class implemented IValueConverter. It can looks like this:

 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;
    }

Finally, you can use it:

    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"/>

Now, if user typed wrong values - DoubleProperty will be null.



来源:https://stackoverflow.com/questions/28615034/wpf-mvvm-textbox-validation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!