【问题标题】:Use StringFormat to add a string to a WPF XAML binding使用 StringFormat 将字符串添加到 WPF XAML 绑定
【发布时间】:2013-10-17 04:40:34
【问题描述】:

我有一个 WPF 4 应用程序,其中包含一个 TextBlock,它单向绑定到一个整数值(在本例中,以摄氏度为单位的温度)。 XAML 如下所示:

<TextBlock x:Name="textBlockTemperature">
        <Run Text="{Binding CelsiusTemp, Mode=OneWay}"/></TextBlock>

这可以很好地显示实际温度值,但我想格式化这个值,使其包含°C 而不仅仅是数字(30°C 而不是 30)。我一直在阅读有关 StringFormat 的内容,并且看到了几个像这样的通用示例:

// format the bound value as a currency
<TextBlock Text="{Binding Amount, StringFormat={}{0:C}}" />

// preface the bound value with a string and format it as a currency
<TextBlock Text="{Binding Amount, StringFormat=Amount: {0:C}}"/>

不幸的是,我所见过的所有示例都没有像我尝试做的那样将字符串附加到绑定值。我敢肯定它一定很简单,但我没有找到它。谁能给我解释一下怎么做?

【问题讨论】:

    标签: c# wpf xaml data-binding string-formatting


    【解决方案1】:

    请注意,在 Bindings 中使用 StringFormat 似乎只适用于“文本”属性。 Using this for Label.Content 不起作用

    【讨论】:

    • 一个非常很重要的一点,我一直在尝试,直到我绝望并发现这条评论来证实我的怀疑。
    • ContentStringFormat 来救场,例如:Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}"
    • 感谢 Casper,真正的英雄发布了这些信息。
    • 对于 GridViewColumn 标题,使用HeaderStringFormat="{}{0} For Report"
    • 如果您使用的是设计时数据,您似乎需要在编辑 ContentStringFormat 后重新构建项目以使更改反映在设计器中,而使用的 StringFormat 说文本框将更新设计器实时。
    【解决方案2】:

    在xml中

    <TextBlock Text="{Binding CelsiusTemp}" />
    

    ViewModel 中,这种设置值的方式也可以:

     public string CelsiusTemp
            {
                get { return string.Format("{0}°C", _CelsiusTemp); }
                set
                {
                    value = value.Replace("°C", "");
                  _CelsiusTemp = value;
                }
            }
    

    【讨论】:

    • 这违背了 View-Viewmodel 分离的全部观点
    • 有时“黑客”是要走的路,为什么不呢?
    • 这不一定总是“hack”。在 ViewModel 中提供格式化文本并在 View 中的多个位置显示它是可以的(View 则不那么笨重)。而ViewModel的作用就是在MVVM中把View和Model分开,不是吗?
    【解决方案3】:

    如果您将 Bi​​nding 放在字符串中间或多个绑定中,这里有一个替代方案,可以很好地提高可读性:

    <TextBlock>
      <Run Text="Temperature is "/>
      <Run Text="{Binding CelsiusTemp}"/>
      <Run Text="°C"/>  
    </TextBlock>
    
    <!-- displays: 0°C (32°F)-->
    <TextBlock>
      <Run Text="{Binding CelsiusTemp}"/>
      <Run Text="°C"/>
      <Run Text=" ("/>
      <Run Text="{Binding Fahrenheit}"/>
      <Run Text="°F)"/>
    </TextBlock>
    

    【讨论】:

    • 我更喜欢这个答案,因为我可以轻松地从字符串库中插入文本。当然,如果您真的担心国际化,您可能最好使用转换器,这样数字和单位的顺序就不是固定的。
    • 这是一个很好的解决方案,但我在文本运行之间的最终文本显示中得到了额外的空格 - 知道为什么吗?在您的示例中,我看到 0 °C ( 32 °F)
    • 如果您想进行实际的字符串格式化(即控制小数位数等),它并不是很有用。
    • @Conrad 如果您不希望每次运行之间有空格,则应将这些运行放在一行中,如下所示:
    【解决方案4】:

    您的第一个示例实际上就是您所需要的:

    <TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />
    

    【讨论】:

    • 为什么xaml中的字符串格式前导空{}
    • @Jonesopolis 它在文档中 - 但如果您的格式字符串以 { 开头,它提供了一种转义机制,因为 {} 在 xaml 中已经有意义。
    • 我看不到文档在哪里解释了前导 {}。
    • @Eric 像很多文档一样,它很臭 - 他们演示它,但不解释。
    • 这里是神秘{}的文档:msdn.microsoft.com/en-us/library/ms744986.aspx
    猜你喜欢
    • 2011-06-30
    • 2017-02-16
    • 2011-03-28
    • 2012-06-16
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    相关资源
    最近更新 更多