2
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 中的东西?

4

3 回答 3

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>
于 2011-04-23T20:54:51.183 回答
0

What you write in the binding markup extension is assigned to the Path property by default, this property is a string so any dynamic content you refer to inside it will not be evaluated. There is no simple XAML-only method to do what you try to do.

于 2011-04-23T20:25:11.950 回答
0

为什么不使用这个:

<StackPanel>
        <ListBox Name="lsbItems" ItemsSource="{Binding Items}" SelectedIndex="{Binding Index}"/>
        <Label Content="{Binding ElementName=lsbItems, Path=SelectedItem}"/>
</StackPanel>
于 2011-04-25T07:05:27.457 回答