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