[英]Bind TextBlock's Text to the SeletedItem text of a ListBox?
I have a ListBox that I provide with DisplayMemberPath
in run time, and have a TextBlock
that I want its Text property to be bound to the selected item text of the ListBox, hardcoding the value works: 我有一个在运行时随DisplayMemberPath
一起提供的ListBox,并且有一个TextBlock
,我希望将其Text属性绑定到ListBox的选定项目文本,对值进行硬编码:
<TextBlock Text="{Binding ElementName=lstBx, Path=SelectedItem.Title}"/>
But how I do it without knowing which property is used for displaying? 但是,如何在不知道用于显示的属性的情况下如何做呢?
Edit 编辑
The ListBox
and the TextBlock
are parts of the ControlTemplate
of a custom control that has a custom DisplayMemberPath
property that I bind to the listBox's DisplayMemberPath
ListBox
和TextBlock
是自定义控件的ControlTemplate
的一部分,该ControlTemplate
具有自定义DisplayMemberPath
属性,该属性已绑定到listBox的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}"/>
In my opinion you have 2 options: 我认为您有2种选择:
SelectedDisplay
property (it should work like SelectedValue
property, but using DisplayMemberPath
instead of SelectedValuePath
) 它具有一种SelectedDisplay
属性(应类似于SelectedValue
属性,但使用DisplayMemberPath
而不是SelectedValuePath
) MultiBinding
and some lamba expression dynimic building. 使用MultiBinding
和一些lamba表达式动态构建。 I will show you the second solution. 我将向您展示第二种解决方案。 First of all the multibinding: 首先是多重绑定:
<TextBlock>
<TextBlock.Text>
<MultiBinding Mode="OneWay" Converter="{StaticResource PropertyMultiValueConverter}">
<Binding ElementName="lstBx" Path="SelectedItem"/>
<Binding ElementName="lstBx" Path="DisplayMemberPath" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Now the code for the PropertyMultiValueConverter
class (of course it can be improved and optimized for avoiding a continuos lambda expression generation): 现在, 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 expressions are faster than using reflection, so I prefer this way. Lambda表达式比使用反射更快,因此我更喜欢这种方式。 As you can see the generated lambda expression retrieves the value of the property and returns it. 如您所见,生成的lambda表达式检索属性的值并返回它。
I think i get your question. 我想我得到你的问题。 Seems you meant SelectedItem.{CanBeAnyProperty} right? 看来您的意思是SelectedItem。{CanBeAnyProperty}对吗?
One solution could be you bind your textblock like below : 一种解决方案是像下面这样绑定文本块:
<TextBlock Text="{Binding ElementName=lstBx, Path=SelectedItem}"/>
And override SelectedItem ToString() method to return appropriate desired property value. 并重写SelectedItem ToString()方法以返回适当的所需属性值。
For example: say your Item bound to list is Person. 例如:说您绑定到列表的项目是Person。
So you can override ToString() method of person class like : 因此,您可以覆盖人员类的ToString()方法,例如:
class Person{
Public string ToString(){
return Name; /*this again you need to work out runtime* OR/
return Age.ToString();}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.