绑定驱动的索引属性不返回

时间:2011-04-23 19:48:44

标签: wpf binding indexed-properties

Public Class View
    Public Property Items As String() = {"One", "Two", "Three"}
    Public Property Index As Integer = 0
End Class

它的实例被设置为此XAML的DataContext:

<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 个答案:

答案 0 :(得分:3)

我担心没有一些代码隐藏是不可能的,但是使用反射和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>

答案 1 :(得分:0)

默认情况下,您在绑定标记扩展中编写的内容被分配给Path属性,此属性是一个字符串,因此您在其中引用的任何动态内容都不会被评估。没有简单的XAML方法来执行您尝试的操作。

答案 2 :(得分:0)

为什么不使用它:

<StackPanel>
        <ListBox Name="lsbItems" ItemsSource="{Binding Items}" SelectedIndex="{Binding Index}"/>
        <Label Content="{Binding ElementName=lsbItems, Path=SelectedItem}"/>
</StackPanel>