Привязка данных индексатора XAML

У меня есть свойство Indexer в классе с именем X, предположим, что X[Y] дает мне другой объект типа Z:

<ContentControl Content="{Binding X[Y]}" ...???

Как я могу сделать DataBinding внутри индексатора? Это работает, если я делаю {Binding [0]}. Но {Binding X[Y]} просто принимает параметр индексатора как строку, которая равна Y.

Обновление: Converter — это вариант, но у меня много классов ViewModel с индексатором и нет аналогичной коллекции, поэтому я не могу позволить себе создавать отдельные преобразователи для всех них. Поэтому я просто хотел знать, что это поддерживается в WPF, если да, то как объявить Content=X[Y], где X и Y являются свойствами DataContext?


person Jobi Joy    schedule 24.11.2009    source источник


Ответы (1)


Я нашел единственный способ сделать это через MultiBinding и IMultiValueConverter.

<TextBlock DataContext="{Binding Source={x:Static vm:MainViewModel.Employees}">
    <TextBlock.Text>
       <MultiBinding Converter="{StaticResource conv:SelectEmployee}">
           <Binding />
           <Binding Path="SelectedEmployee" />
       </MultiBinding>
    </TextBlock.Text>
</TextBlock>

И ваш преобразователь:

public class SelectEmployeeConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
        object parameter, CultureInfo culture)
    {
        Debug.Assert(values.Length >= 2);

        // change this type assumption
        var array = values[0] as Array;
        var list = values[0] as IList;
        var enumerable = values[0] as IEnumerable;
        var index = Convert.ToInt32(values[1]);

        // and check bounds
        if (array != null && index >= 0 && index < array.GetLength(0))
            return array.GetValue(index);
        else if (list != null && index >= 0 && index < list.Count)
            return list[index];
        else if (enumerable != null && index >= 0)
        {
            int ii = 0;
            foreach (var item in enumerable)
            {
                if (ii++ == index) return item;
            }
        }

        return Binding.DoNothing;
    }

    public object[] ConvertBack(object value, Type[] targetTypes,
        object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
person user7116    schedule 24.11.2009
comment
Да, спасибо, и это очевидное решение, если есть только один класс. Но у меня есть много классов ViewModel, подобных этому, поэтому я не могу позволить себе иметь отдельные преобразователи, вместо этого я меняю логику индексатора на что-то другое. - person Jobi Joy; 25.11.2009
comment
Я пошел дальше и обновил это, чтобы работать с множеством типов коллекций. - person user7116; 30.08.2011