1

I have a Form that contains some TextBox bound to some object property:

<Label Content="Car Id:"/>
<TextBox Text="{Binding Path=Car.CarId, Mode=TwoWay}"/>

I have an "OK Button" mapped to a CanExecute() command like this (not showing the event part, but be sure it works):

private bool CanExecute()
{
    return _vm.Model.Car.CarId !=0;
}

Issue:

  • If I set the Car Id field to something, the button is enabling.
  • If I delete the value of the Car Id, nothing happens. Debugging, the Car.CarId is actually still set to the value that I set previously!

Thank you in advance for your tips on that!

goul
  • 813
  • 1
  • 13
  • 32

4 Answers4

5

from another answer here on stackoverflow

int property can not work. and yes then your setter is not called, even a converter would not be called. if you want such a behavior use a string property in your viewmodel and convert the value to your int property in your model if needed

but you can use Nullable int with TargetNullValue=''

<TextBox Text="{Binding MyNullableInt, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, TargetNullValue=''}"/>
blindmeis
  • 22,175
  • 7
  • 55
  • 74
2

Assuming that CarId is an int and not string you probably receive a FormatException. If you create an IValueConverter and add it to the binding you can prevent exception(s).

The problem is when you input a CarId and its a number, WPF can bind it and will be set as value in your VM. But next time, when the value is invalid (means not convertible to int) will not be set (exception occours in WPF mscorelib.dll), means old value is still there. Property setter will be never called in this case.

Something like this:

public class FallbackConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
     int v = 0; // default if no value provided or value is not convertible to int
     if (value != null)
     {
        var result = int.TryParse(value.ToString(), out v);
     }

     return v;
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
     string result = string.Empty;
     if (value != null)
     {
        result = value.ToString();
     }

     return result;
  }

}

In XAML (ofcourse replace to your namespace):

xmlns:converter="clr-namespace:Client.ViewModels.Converters"

Then:

<converter:FallbackConverter x:key="FallbackConverter "/>

<TextBox Text="{Binding Path=Car.CarId, Mode=TwoWay, Converter={StaticResource FallbackConverter}}"/>
Andras Sebo
  • 1,120
  • 8
  • 19
1

You are checking if the CarID is "0" if you just delete the value of the TextBox this will not result in a value of "0". Please try to change the type of CarId to string and in the "CanExecute"-Method check againt string.Empty, like this:

private bool CanExecute()
{
    return _vm.Model.Car.CarId != string.Empty;
}

If you need CarId to be an Integer you should set it to nullable and check against a null value:

Declaration of CarID:

int? CarID;

Check:

private bool CanExecute()
{
    return _vm.Model.Car.CarId != null;
}
Romano Zumbé
  • 7,893
  • 4
  • 33
  • 55
  • I also thought about the nullable int, but it seems like the Binding is populating an empty input as empty string, not as null, so the setter of CarId doesn't get called. So you would have to include a converter which converts an empty string to null in the ConvertBack()-method – Florian Gl Jun 19 '13 at 06:13
  • Since the user can input data into the TextBox and it doesn't seem to check for a qualified integer before updating the binding (since it is TwoWay) I would suggest to use string as dataType for the CarId. Or to implement the behavior I've desribed in the prior sentence and a converter like Florian GI mentioned (perhaps both in the converter). – Romano Zumbé Jun 19 '13 at 06:43
  • If using string as type, I would suggest adding a Validator to check if the input is an integer: http://wpftutorial.net/DataValidation.html so @goul wouldn't have to check this when converting to an int. – Florian Gl Jun 19 '13 at 06:50
0

add to the binding

, UpdateSourceTrigger=PropertyChanged
ZSH
  • 905
  • 5
  • 15