【问题标题】:WPF StringFormat on Label Content标签内容上的 WPF StringFormat
【发布时间】:2023-04-01 17:56:02
【问题描述】:

我想将我的字符串绑定格式化为Amount is X,其中X 是绑定到标签的属性。

我看过很多例子,但以下不起作用:

<Label Content="{Binding Path=MaxLevelofInvestment, 
   StringFormat='Amount is {0}'}" />

我也试过这些组合:

StringFormat=Amount is {0}
StringFormat='Amount is {}{0}'
StringFormat='Amount is \{0\}'

我什至尝试将绑定属性的数据类型更改为int、string和double。似乎没有任何效果。这是一个非常常见的用例,但似乎不受支持。

【问题讨论】:

    标签: wpf wpf-controls binding wpftoolkit wpfdatagrid


    【解决方案1】:

    你可以在下面使用这个

    <Label Content="{Binding Content, StringFormat='Page Data> {0}'}" />
    

    “内容”是一个绑定变量,在单引号之间键入您的文本。 {0} 将插入内容数据的位置。

    【讨论】:

    • 标签没有文本属性
    • @PeterBruins 是的,你说得对,我把 winForms 搞混了。它具有content 属性而不是text。 text 属性存在于 winForms 感谢您的评论
    【解决方案2】:

    这不起作用的原因是Label.Content 属性的类型为Object,而Binding.StringFormat 仅在绑定到String 类型的属性时使用。

    正在发生的事情是:

    1. Binding 将您的 MaxLevelOfInvestment 值装箱并将其存储为 Label.Content 属性作为装箱的十进制值。
    2. Label 控件有一个包含ContentPresenter 的模板。
    3. 由于未设置ContentTemplate,ContentPresenter 查找为Decimal 类型定义的DataTemplate。如果没有找到,它会使用默认模板。
    4. ContentPresenter 使用的默认模板通过使用标签的 ContentStringFormat 属性来呈现字符串。

    有两种可能的解决方案:

    • 使用 Label.ContentStringFormat 代替 Binding.StringFormat,或者
    • 使用 TextBlock.Text 等字符串属性代替 Label.Content

    这里是如何使用 Label.ContentStringFormat:

    <Label Content="{Binding Path=MaxLevelofInvestment}" ContentStringFormat="Amount is {0}" />
    

    下面是如何使用 TextBlock:

    <TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is {0}'}" />
    

    注意:为简单起见,我在上面的解释中省略了一个细节:ContentPresenter 实际上使用了自己的Template 和StringFormat 属性,但是在加载过程中这些属性会自动模板绑定到ContentTemplate 和@987654342 Label 的@ 属性,所以看起来ContentPresenter 实际上是在使用Label 的属性。

    【讨论】:

    • 感谢您的详细解释,现在说得通了。由 WPF 团队为未来做好准备。
    • 我喜欢你的回答,你知道如何使用 2 个参数而不是 1 个吗?在这里真的很挣扎(比如 TextBlock stringFormat 可以在使用触发器等时处理多个)。
    • 为什么在这种情况下您需要将 Path= 放在绑定前面?通常我可以做Content="{Binding MaxLevelofInvestment}",它工作得很好......
    • 为了后代:如果您以 {0} 开始 ContentStringFormat,请不要忘记在其前面加上 {}。所以让它ContentStringFormat="{}{0} some text here"
    • 对于后代,请参阅 stackoverflow.com/a/7980937/120440 以了解 {} 的目的——在您理解原因之前,这令人费解。
    【解决方案3】:

    制作一个通用的StringFormatConverter : IValueConverter。将您的格式字符串传递为ConverterParameter。

    Label Content="{Binding Amount, Converter={...myConverter}, ConverterParameter='Amount is {0}'"
    

    另外,当您在格式字符串中需要多个对象时,请创建StringFormatMultiConverter : IMultiValueConverter,例如Completed {0} tasks out of {1}。

    【讨论】:

    • 我喜欢这个。我可以看到使用纯 XAML 方法或值转换器的价值。
    【解决方案4】:

    我刚刚检查过,由于某种原因,它不适用于 Label,可能是因为它在内部使用 ContentPresenter 作为 Content 属性。您可以改用 TextBlock,这样就可以了。如果您需要继承样式、行为等,也可以将下面的 TextBlock 摘录放在标签的内容中。

    <TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is \{0\}'} />
    

    【讨论】:

      【解决方案5】:

      尝试使用转换器....

      <myconverters:MyConverter x:Key="MyConverter"/>
      
      
      <Label Content="{Binding Path=MaxLevelofInvestment, Converter={StaticResource MyConverter"} />
      
      
      public class MyConverter : IValueConverter
      {
          public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
          {
              return String.Format("Amount is {0}", value);
          }
      
          public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
          {
              return value;
          }
      }
      

      【讨论】:

      • 这太过分了。我解释了问题的原因,并在我的回答中提出了两个简单的解决方案。
      • 我同意这隐藏了用法,我最近继承了一个采用这种方法的项目,并且更喜欢开发人员使用 StringFormat 中的构建而不是自己滚动。
      猜你喜欢
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2020-07-13
      • 2015-05-02
      • 2013-06-18
      • 1970-01-01
      • 2021-06-30
      相关资源
      最近更新 更多