将TextBlock的Text绑定到ListBox的SeletedItem文本?

时间:2018-02-17 10:34:37

标签: c# wpf data-binding listbox

我有一个ListBox,我在运行时提供了DisplayMemberPath,并且有一个TextBlock我希望它的Text属性绑定到ListBox的选定项文本,硬编码值工作:

<TextBlock Text="{Binding ElementName=lstBx, Path=SelectedItem.Title}"/>

但是我怎么做而不知道哪个属性用于显示?

修改

ListBoxTextBlock是自定义控件的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}"/>

2 个答案:

答案 0 :(得分:1)

在我看来,你有两个选择:

  1. 创建自己的Listbox扩展程序。它有一种SelectedDisplay属性(它应该像SelectedValue属性一样,但使用DisplayMemberPath代替SelectedValuePath
  2. 使用MultiBinding和一些lamba表达式dynimic building。
  3. 我会告诉你第二个解决方案。首先是多重绑定:

    <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();}
}