1

I have a MultiBinding that is not working on TextBox.Text. I have the same code that is binding properly to Value of Extended WPF Toolkit's IntegerUpDown.

It is going through an IMultiValueConverter that takes the bound POCO and the listbox it is part of (it is displaying the order of the item in the listbox)

Here is the code:

<!--works-->
<wpf:IntegerUpDown ValueChanged="orderChanged" x:Name="tripOrder">
    <wpf:IntegerUpDown.Value>
        <MultiBinding Converter="{StaticResource listBoxIndexConverter}" Mode="OneWay">
            <Binding />
            <Binding ElementName="listTrips" />
        </MultiBinding>
    </wpf:IntegerUpDown.Value>
</wpf:IntegerUpDown>
<!--doesn't work-->
<TextBox x:Name="tripOrder2">
    <TextBox.Text>
        <MultiBinding Converter="{StaticResource listBoxIndexConverter}" Mode="OneWay">
            <Binding />
            <Binding ElementName="listTrips" />
        </MultiBinding>
    </TextBox.Text>
</TextBox>

Here is the result:

result

I don't believe it is relevant, but just in case, here is the class that performs the conversion:

    public class ListBoxIndexConverter : IMultiValueConverter
    {

    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var trip = values[0] as TripBase;

        if (trip == null)
        {
            return null;
        }

        var lb = values[1] as CheckListBox;
        if (lb == null)
        {
            return null;
        }

        //make it 1 based
        return lb.Items.IndexOf(trip) + 1;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}
Tim Hibbard
  • 113
  • 1
  • 7
  • When do your bound properties fire their PropertyChanged events. Can you verify that they are firing at the times that you are expecting the bindings to get updated? – Alain May 08 '12 at 16:11

2 Answers2

2

The converter should return the type that the property expects. The reason is that in regular use of the properties (i.e. without Binding), the properties may have type converters that convert from one type (or more) to the type required by the property. For example, when you write:

<ColumnDefinition Width="Auto"/>

there's a converter that converts string "Auto" to:

new GridLength(1, GridUnitType.Auto)

When using binding, this mechanism is bypassed since the converter should return the right type.

So, to fix your issue, at the return of your converter:

return (lb.Items.IndexOf(trip) + 1).ToString();

This should fix the TextBox.

Now, for the IntegerUpDown. It sounds like it actually expects to receive an int and returning a string will break it. So, again, change the return of the converter:

if (targetType == typeof(int))
{
    return lb.Items.IndexOf(trip) + 1;
}
else if (targetType == typeof(string))
{
    return (lb.Items.IndexOf(trip) + 1).ToString();
}
else
{
    throw new NotImplementedException(String.Format("Can not convert to type {0}", targetType.ToString()));
}
XAMeLi
  • 6,189
  • 2
  • 22
  • 29
0

The binding is not going to work, because the listTrips is not changing when the list box's selected value changes. The thing that changes is listTrips.SelectedItem, so you should bind against it:

<Binding Path="SelectedItem" ElementName="listTrips"/>

Actually, I wonder why it works for the first example.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • @Tim: than replace `Text` with `SelectedItem`. – Vlad May 08 '12 at 16:13
  • `` is a POCO (TripBase) that implements `INotifyPropertyChanged` – Tim Hibbard May 08 '12 at 16:13
  • Could you check if `NotifyPropertyChanged` is firing for `trip`? – Vlad May 08 '12 at 16:16
  • `Trip` fires change notifications as expected. My concern is why IntegerUpDown works as expected (I think `Value` gets mapped to a `TextBox` internally), but `TextBox` doesn't. – Tim Hibbard May 08 '12 at 16:20
  • @Tim: if `Trip` fires the notifications, could you check if the converter gets called? – Vlad May 08 '12 at 16:26
  • I set a breakpoint in the `Convert` method of the converter. It fired once for every item in the `ListBox` when the `ListBox` was first loaded with items, then once again for each item in the `ListBox` when the `ListBox` was modified. – Tim Hibbard May 08 '12 at 16:34