Индексированное свойство на основе привязки не возвращает - PullRequest
2 голосов
/ 23 апреля 2011
Public Class View
    Public Property Items As String() = {"One", "Two", "Three"}
    Public Property Index As Integer = 0
End Class

Его экземпляр установлен как DataContext этого XAML:

<Window>
    <StackPanel>
        <ListBox ItemsSource="{Binding Items}" SelectedIndex="{Binding Index}"/>
        <Label Content="{Binding Items[Index]}"/>
    </StackPanel>
</Window>

Но это не работает.

<Label Content="{Binding Items[{Binding Index}]}"/>

Это тоже.

<Label Content="{Binding Items[0]}"/>

Это работает.

Есть ли какое-либо решение, кроме создания дополнительных свойств в поле зрения? Что-то прямо в XAML?

Ответы [ 3 ]

3 голосов
/ 24 апреля 2011

Боюсь, что это невозможно без некоторого кода, но используя отражение и dynamic, вы можете создать конвертер, который может это сделать (это было бы возможно без dynamic, но более сложным):

public class IndexerConverter : IValueConverter
{
    public string CollectionName { get; set; }
    public string IndexName { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Type type = value.GetType();
        dynamic collection = type.GetProperty(CollectionName).GetValue(value, null);
        dynamic index = type.GetProperty(IndexName).GetValue(value, null);
        return collection[index];
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Положите в ресурсы следующее:

<local:IndexerConverter x:Key="indexerConverter" CollectionName="Items" IndexName="Index" />

и используйте его так:

<Label Content="{Binding Converter={StaticResource indexerConverter}}"/>

РЕДАКТИРОВАТЬ: Предыдущее решение не обновляется должным образом при изменении значений, это делает:

public class IndexerConverter : IMultiValueConverter
{
    public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((dynamic)value[0])[(dynamic)value[1]];
    }

    public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

В ресурсах:

<local:IndexerConverter x:Key="indexerConverter"/>

Использование:

<Label>
    <MultiBinding Converter="{StaticResource indexerConverter}">
        <Binding Path="Items"/>
        <Binding Path="Index"/>
    </MultiBinding>
</Label>
0 голосов
/ 25 апреля 2011

Почему бы не использовать это:

<StackPanel>
        <ListBox Name="lsbItems" ItemsSource="{Binding Items}" SelectedIndex="{Binding Index}"/>
        <Label Content="{Binding ElementName=lsbItems, Path=SelectedItem}"/>
</StackPanel>
0 голосов
/ 24 апреля 2011

То, что вы пишете в расширении разметки привязки, по умолчанию присваивается свойству Path, это свойство является строкой, поэтому любое динамическое содержимое, на которое вы ссылаетесь внутри, не будет оцениваться. Не существует простого метода только для XAML, чтобы делать то, что вы пытаетесь сделать.

...