【问题标题】:WPF binding with StringFormat doesn't work on ToolTipsWPF 与 StringFormat 的绑定在 ToolTips 上不起作用
【发布时间】:2010-09-16 20:39:52
【问题描述】:

以下代码有一个简单的绑定,它使用完全相同的绑定表示法将名为 MyTextBlock 的 TextBlock 的 Text 绑定到 TextBox 的 Text 和 ToolTip 属性:

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox    Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}"
             ToolTip="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}" />
</StackPanel>

绑定还使用了StringFormat property introduced with .NET 3.5 SP1,它对上述 Text 属性运行良好,但对于 ToolTip 似乎已损坏。预期的结果是“它是:Foo Bar”,但是当您将鼠标悬停在 TextBox 上时,工具提示仅显示绑定值,而不是字符串格式的值。有什么想法吗?

【问题讨论】:

标签: wpf binding


【解决方案1】:

WPF 中的工具提示可以包含任何内容,而不仅仅是文本,因此它们为您只需要文本的时间提供了 ContentStringFormat 属性。据我所知,您需要使用扩展语法:

<TextBox ...>
  <TextBox.ToolTip>
    <ToolTip 
      Content="{Binding ElementName=myTextBlock,Path=Text}"
      ContentStringFormat="{}It is: {0}"
      />
  </TextBox.ToolTip>
</TextBox>

我不能 100% 确定使用嵌套属性中的 ElementName 语法进行绑定的有效性,但 ContentStringFormat 属性正是您要寻找的。​​p>

【讨论】:

  • 我明白了,我认为 ToolTip 只是一个普通字符串,就像在 Windows 窗体中一样。是的,在这种情况下 ElementName 语法无法访问外部元素。
  • 请注意,仅当您将 {0} 放在字符串的开头时才需要 {},因此您需要它来与其他 xaml 标记区分开来。
  • 头脑=被吹了。我刚刚打了这个,就像“waaaat?”
  • 当没有指定转换器时,它真的让我觉得 stringformat 不能“正常工作”。我必须编写自己的 stringformatConverter。 MS又掉球了……
  • StringFormat 仅在 TargetType 是字符串类型时应用。 ToolTip 内容类型为 object
【解决方案2】:

这可能是一个错误。 当您对工具提示使用短语法时:

<TextBox ToolTip="{Binding WhatEverYouWant StringFormat='It is: \{0\}'}" />

StringFormat 被忽略,但是当您使用扩展语法时:

<TextBox Text="text">
   <TextBox.ToolTip>
      <TextBlock Text="{Binding WhatEverYouWant StringFormat='It is: \{0\}'}"/>
   </TextBox.ToolTip>
</TextBox>

它按预期工作。

【讨论】:

  • 最准确的答案..谢谢!
  • WhatEverYouWant 编译后缺少逗号
【解决方案3】:

正如马特所说,工具提示可以包含任何内容,因此您可以在工具提示中绑定一个 TextBox.Text。

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}">
        <TextBox.ToolTip>
            <TextBlock>
                <TextBlock.Text>
                    <Binding ElementName=MyTextBlock Path="Text" StringFormat="It is: {0}" />
                </TextBlock.Text>
            </TextBlock>
        </TextBox.ToolTip>
    </TextBox>
</StackPanel>

您甚至可以在 ToolTip 内堆叠一个网格并根据需要对文本进行布局。

【讨论】:

    【解决方案4】:

    你的代码可以这么短:

    <TextBlock ToolTip="{Binding PrideLands.YearsTillSimbaReturns,
        Converter={StaticResource convStringFormat},
        ConverterParameter='Rejoice! Just {0} years left!'}" Text="Hakuna Matata"/>
    

    我们将使用转换器永远不会被忽略这一事实,这与 StringFormat 不同。

    把这个放到StringFormatConverter.cs

    using System;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    
    namespace TLKiaWOL
    {
        [ValueConversion (typeof(object), typeof(string))]
        public class StringFormatConverter : IValueConverter
        {
            public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (ReferenceEquals(value, DependencyProperty.UnsetValue))
                    return DependencyProperty.UnsetValue;
                return string.Format(culture, (string)parameter, value);
            }
    
            public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotSupportedException();
            }
        }
    }
    

    将其放入您的 ResourceDictionary.xaml

    <conv:StringFormatConverter x:Key="convStringFormat"/>
    

    【讨论】:

    • 虽然我更喜欢最佳答案,但 ElementBinding 问题让我大吃一惊。这个答案适用于我的情况,而其他人没有。
    【解决方案5】:

    在这种情况下,您可以使用相对绑定:

    <StackPanel>
        <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
        <TextBox Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}"
                 ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" />
    </StackPanel>
    

    【讨论】:

      【解决方案6】:

      以下是一个冗长的解决方案,但它有效。

      <StackPanel>
        <TextBox Text="{Binding Path=., StringFormat='The answer is: {0}'}">
          <TextBox.DataContext>
            <sys:Int32>42</sys:Int32>
          </TextBox.DataContext>
          <TextBox.ToolTip>
            <ToolTip Content="{Binding}" ContentStringFormat="{}The answer is: {0}" />
          </TextBox.ToolTip>
        </TextBox>
      </StackPanel>
      

      我更喜欢更简单的语法,类似于我最初问题中的语法。

      【讨论】:

      • @Shimmy:旁观者眼中的“更好”,可以将自己的问题标记为已接受的答案
      • @Shimmy 更糟糕的是,他的回答还包括一个“42”笑话。
      • @Andomar,更好的是人们用他们的投票来决定,这里也特别,它几乎是相同的答案。让人们回答你的问题,然后复制他们的答案并获得声誉,因为这是一种完全错误的态度。
      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 2011-03-26
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 2011-03-11
      • 1970-01-01
      相关资源
      最近更新 更多