2
votes

If we have a combobox bound 'twoway' to a TimeSpan property on a view model, and a converter changing the timespan view model property to a string, adding a 'm' for minutes, then when editing the combobox value from say 10m to 5, I would expect:

WPF Binding calls ConvertBack to get value to update source property - let's assume that is a timespan for 5 minutes.

The view model's timespan property setter is called and sets the underlying field (changing from timespan of 10 to 5) and then raises OnPropertyChanged

WPF Binding receives event and therefore calls its handler method, which first does a Convert for the value, and then sets this '5m' converted value to the target text property

Except, the last step does not happen, and the comboxbox remains at 5. I actually want this behaviour, but would like to understand why the last step does not happen. Strange thing is changing to a textbox does give the behaviour I expect (updating 5 to 5m immediately)

EDIT: original question mistakenly stated textbox where I should have written combobox

UPDATE: using the snoop utility, I see that the text property of combobox does become 5m, but display remains 5 - I can only assume if the combobox is being edited, it does not refresh its text display. Changed title of question from "WPF Data Binding Target-Source-Target cycle using converter" to more accurately reflect what it now is.

2

2 Answers

2
votes

Can you show your sample code where you are facing this issue because this sample code works for me -

XAML:

<TextBox Text="{Binding Time, Converter={StaticResource MyConverter}}"/>

Property

public TimeSpan Time
{
   get
   {
      return time;
   }
   set
   {
      if (time != value)
      {
         time = value;
         OnPropertyChanged("Time");
      }
   }
}

Converter

public class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is TimeSpan)
            {
                return ((TimeSpan)value).Minutes.ToString() + "m";
            }
            return String.Empty;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string)
            {
                return new TimeSpan(0, System.Convert.ToInt32(value), 0);
            }
            return new TimeSpan();
        }
    }
0
votes

ConvertBack method of the converter will only set the value of Binding source property, then your target property (i.e Text of ypur TextBox) would not be updated.If it would be so then there would be infinite loop everytime when the bindingmode of the binding would be TwoWay.Convert Method is called when there is change in source property and ConvertBack is called when there is change in the target property of the binding. Hope this will help.