【问题标题】:Bind textblock to two properties将文本块绑定到两个属性
【发布时间】:2011-09-15 17:47:39
【问题描述】:

我有一个绑定到 ItemsSource 集合中的属性的 Textblock。我想在同一个文本块中显示该类的两个属性,但似乎我一次只能执行一个绑定。 我目前有这个:

Text="{Binding Title}"

但我想附加另一个属性,所以理论上它会是:

Text="{Binding Title - Author}" 

输出看起来像“莎士比亚 - 罗密欧与朱丽叶”。我尝试添加逗号、另一个绑定和其他内容,但它们都会导致抛出异常(例如元素 TextBlock 上的未知属性 Text)。

两个属性都来自同一个类,所以我不需要两个数据源。

【问题讨论】:

  • 您使用的是 MVVM 模式吗?如果是这样,只需在您的视图模型上创建另一个以您希望的方式返回字符串的属性。
  • 如果您使用的是 MVVM 模式中的 ViewModel,您只需添加一个属性即可满足您的需求。顺便说一句,为什么不使用 2-3 texblocks?
  • 不使用 MVVM。我尝试使用多个文本块,但我需要将文本彼此相邻放置,并且某些文本比其他文本长,因此将它们完全对齐会很棘手。

标签: c# silverlight xaml binding textblock


【解决方案1】:

听起来你需要MultiBinding

<TextBlock.Text>
    <MultiBinding StringFormat="{}{0} - {1}">
        <Binding Path="Title" />
        <Binding Path="Author" />
    </MultiBinding>
</TextBlock.Text>

【讨论】:

    【解决方案2】:

    不幸的是,silverlight 缺少一些 WPF 可以处理的部分。我可能会使用值转换器,您可以传递包含标题和作者的类来格式化文本。

    代码如下:

    public class TitleAuthorConverter : IValueConverter
    {
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is Book)) throw new NotSupportedException();
            Book b = value as Book;
            return b.Title + " - " + b.Author;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
    }
    

    还有一些 XAML:

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>
            <local:Book Title="Some Book" Author="Some Author" x:Key="MyBook"/>
            <local:TitleAuthorConverter x:Key="Converter"/>
        </Grid.Resources>
        <TextBlock DataContext="{StaticResource MyBook}" Text="{Binding Converter={StaticResource Converter}}"/>
    </Grid>
    

    这种方式的缺点是,如果属性更改(即您实现 INotifyPropertyChanged),您将无法更新文本,因为该字段已绑定到类。

    正如问题 cmets 中所建议的那样,您还可以创建第三个属性来组合它们。这样就不必使用多重绑定或值转换器了。

    【讨论】:

    • 谢谢。我将使用一个值转换器,因为它的属性在运行时不会改变。
    【解决方案3】:

    我在网上找到了一个 Silverlight 的 MultiBinding 示例项目,我相信其中有很多,只需 Google 一下。如果找不到,请告诉我,我会寄给您我们正在使用的那个。 有谁知道多重绑定是否会出现在 SL 5 中?你也可以使用第三个属性,只要记住触发它的 PropertyChanged 事件,只要它的任何一个组成部分发生变化,那么绑定就可以了。

    【讨论】:

      【解决方案4】:

      使用这个..它会完美地工作。

      <TextBlock>
          <Run Text="{Binding Title}"></Run>
          <Run Text=":"></Run>
          <Run Text="{Binding Author}"></Run> 
      </TextBlock>
      

      输出会是这样的,

      哎呀:Balagurusamy

      【讨论】:

      • 太棒了。像魅力一样工作:D
      【解决方案5】:
      <TextBlock.Text>
      <MultiBinding StringFormat="{}{0} - {1}">
          <Binding Path="Title" />
          <Binding Path="Author" />
      </MultiBinding>
      

      【讨论】:

      • 这是在另一个答案中提出的,但在 Silverlight 中不可用。
      【解决方案6】:

      如果您要在 UI 中显示的文本是只读的,您可以尝试覆盖视图模型对象的 ToString 并返回组合值。

      返回标题+“:”+作者;

      【讨论】:

        【解决方案7】:

        一个非常简单的解决方案是在您的 ViewModel 中拥有这样的属性:

                public string TextblockDataProvider
            {
                get
                {
                    return string.Format("{0} - {1}", Title, Author);
                }
                set { ; }
            }
        

        并在 xaml 中绑定:

        Text="{Binding TextblockDataProvider}"
        

        【讨论】:

          【解决方案8】:

          您可以使用CodeProject的特殊扩展名

          例子

          <TextBlock>
          <TextBlock.Text>
              <MultiBinding StringFormat="{}{0} {1}" >
                  <Binding Path="FirstName" />
                  <Binding Path="LastName" />
              </MultiBinding>
          </TextBlock.Text>
          </TextBlock>
          

          【讨论】:

            猜你喜欢
            • 2013-03-21
            • 1970-01-01
            • 2019-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-07
            • 1970-01-01
            相关资源
            最近更新 更多