0

For some reason, the IMultiValueConverter is not setting my property through ConvertBack function.

My custom ComboBox XAML looks like this:

<ComboBox.SelectedIndex>
    <MultiBinding Converter="{StaticResource IDToIndex}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnTargetUpdated="True">
        <Binding Path="SelectedID" ElementName="InnerComboBoxName"/>
        <Binding Path="ItemsSource" ElementName="InnerComboBoxName"/>
    </MultiBinding>
</ComboBox.SelectedIndex>

and the IMultiValueConverter like this:

public class IndexIDConverter : System.Windows.Data.IMultiValueConverter
{
    private IDDisplayList tmp = new IDDisplayList();

    public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture )
    {
        if ( values[0] == DependencyProperty.UnsetValue )
            values[0] = -1;
        if ( values[1] == DependencyProperty.UnsetValue )
            values[1] = new IDDisplayList();

        int? ajdi = (int?) values[0];
        IDDisplayList lista = (IDDisplayList) values[1];
        tmp = lista;

        int? index = lista?.IndexOf( lista?.Where( x => x.ID == ajdi )?.FirstOrDefault() );

        return index == null ? -1 : index;
    }

    public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture )
    {
        if ( value == DependencyProperty.UnsetValue )
            value = -1;

        int index = (int)value;
        int? id = tmp[index].ID;

        return new object[] { id, tmp };
    }
}

Here is my Binding inside of a Page:

<V3:ComboBox ItemsSource="{Binding Source={x:Static s:CachedData.Areas}}" 
             SelectedID="{Binding AreaID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
                          NotifyOnTargetUpdated=True}"/>

Everything is working fine. Converter is being called upon opening the Page, the SelectedIndex property is being set correctly, and when I pick something from the ComboBox, the ConvertBack is being called. Now, I have the values in my id and tmp properties just the way I need them to be, but the SelectedID property of the ComboBox stays the same. Does anyone sees the issue here?

Adder
  • 165
  • 1
  • 14
  • 1
    Don't store any state in an `IValueConverter` class. It will only cause problems. Remove the `tmp` field. – dymanoid Sep 20 '17 at 14:56
  • @dymanoid I did, `SelectedID` is still not being updated. – Adder Sep 20 '17 at 15:02
  • That was not an answer *why it doesn't work*, it was just a random comment in order to help you improving your skills and your code quality. Don't store any state in **any** `IValueConverter` implementation, not just in this one. – dymanoid Sep 20 '17 at 15:04
  • @dymanoid And why not? It is just a class that implements `IValueConverter` and it gets its own instance for every binding. – Adder Sep 20 '17 at 15:17
  • 1
    The fact that you use a new instance for each new binding is a) resource wasting and b) won't always be so, because software development occurs nowadays in teams. Some other developer might use your implementation without knowing that it has these "specialties". So therefore this is a bad design decision. – dymanoid Sep 20 '17 at 15:20
  • @dymanoid I don't create a new instance, it is done so by the WPF by default. – Adder Sep 20 '17 at 15:40
  • @Adder The point is you can not *rely* on having a converter instance per binding. Converters may always be shared. So listen to what people are telling you here and don't store state in binding converters. Never. – Clemens Sep 20 '17 at 20:22
  • The thing is - the new instance was created every time for me, that part worked fine. Today I did some research on that an it turns out you are both right. Some say the same converter instance is used for every binding, but I think that is only true for `IValueConverter`, not for the `IMultiValueConverter`. Anyway, thank you both for comments, I managed to work this out without it. – Adder Sep 21 '17 at 08:06
  • Also, for anyone else trying something similar, the answer is, like @Clemens said in the other post, to use `SelectedValue` and `SelectedValuePath`. – Adder Sep 21 '17 at 08:08

0 Answers0