我有一个ListBox,我在运行时提供了DisplayMemberPath
,并且有一个TextBlock
我希望它的Text属性绑定到ListBox的选定项文本,硬编码值工作:
<TextBlock Text="{Binding ElementName=lstBx, Path=SelectedItem.Title}"/>
但是我怎么做而不知道哪个属性用于显示?
修改
ListBox
和TextBlock
是自定义控件的ControlTemplate
的一部分,该控件具有我绑定到listBox DisplayMemberPath
的自定义DisplayMemberPath
属性
<ListBox Name="lstBx" ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ItemsSource}"
DisplayMemberPath="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisplayMemberPath}"
SelectedValuePath="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedValuePath}"/>
答案 0 :(得分:1)
在我看来,你有两个选择:
SelectedDisplay
属性(它应该像SelectedValue
属性一样,但使用DisplayMemberPath
代替SelectedValuePath
)MultiBinding
和一些lamba表达式dynimic building。我会告诉你第二个解决方案。首先是多重绑定:
<TextBlock>
<TextBlock.Text>
<MultiBinding Mode="OneWay" Converter="{StaticResource PropertyMultiValueConverter}">
<Binding ElementName="lstBx" Path="SelectedItem"/>
<Binding ElementName="lstBx" Path="DisplayMemberPath" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
现在是PropertyMultiValueConverter
类的代码(当然可以改进和优化它以避免连续lambda表达式生成):
public class PropertyMultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
object selectedItem = values[0];
string displayMemberPath = values[1] as string;
if (selectedItem != null)
{
ParameterExpression param =
System.Linq.Expressions.Expression.Parameter(selectedItem.GetType(), "x");
MemberExpression body =
System.Linq.Expressions.Expression.Property(param, displayMemberPath);
LambdaExpression lambda =
System.Linq.Expressions.Expression.Lambda(body, param);
Delegate expression = lambda.Compile();
return expression.DynamicInvoke(selectedItem);
}
else
{
return null;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Lambda表达式比使用反射更快,所以我更喜欢这种方式。如您所见,生成的lambda表达式检索属性的值并返回它。
答案 1 :(得分:0)
我想我得到了你的问题。看起来你的意思是SelectedItem。{CanBeAnyProperty}对吗?
一种解决方案可能是绑定您的文本块,如下所示:
<TextBlock Text="{Binding ElementName=lstBx, Path=SelectedItem}"/>
并覆盖SelectedItem ToString()方法以返回适当的所需属性值。
例如:说你绑定到列表的Item是Person。
所以你可以覆盖人类的ToString()方法,如:
class Person{
Public string ToString(){
return Name; /*this again you need to work out runtime* OR/
return Age.ToString();}
}