Multibinding не работает на TextBox.Text

У меня есть MultiBinding, который не работает на TextBox.Text. У меня есть тот же код, который правильно привязывается к значению расширенного набора инструментов WPF IntegerUpDown.

Он проходит через IMultiValueConverter, который принимает связанный POCO и список, частью которого он является (он отображает порядок элемента в списке)

Вот код:

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

Вот результат:

результат

Я не верю, что это актуально, но на всякий случай вот класс, который выполняет преобразование:

    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
}

2 ответа

Решение

Преобразователь должен возвращать тип, который ожидает свойство. Причина в том, что при регулярном использовании свойств (т.е. без Binding), свойства могут иметь преобразователи типов, которые преобразуют из одного типа (или более) в тип, требуемый свойством. Например, когда вы пишете:

<ColumnDefinition Width="Auto"/>

есть конвертер, который преобразует строку "Авто" в:

new GridLength(1, GridUnitType.Auto)

При использовании привязки этот механизм обходится, поскольку преобразователь должен возвращать правильный тип.

Итак, чтобы исправить вашу проблему, при возврате вашего конвертера:

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

Это должно исправить TextBox,

Теперь для IntegerUpDown, Похоже, что на самом деле ожидает получить int и возвращение строки сломает ее. Итак, еще раз измените возврат конвертера:

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

Привязка не будет работать, потому что listTrips не изменяется при изменении выбранного значения в списке. То, что меняется, это listTrips.SelectedItemтак что вы должны связать это:

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

На самом деле, мне интересно, почему это работает для первого примера.

Другие вопросы по тегам