使用字符串连接而不是 TextBlocks 堆栈

100

我想在WPF ItemsControl中显示一个客户对象列表。我为此创建了一个DataTemplate:

    <DataTemplate DataType="{x:Type myNameSpace:Customer}">
        <StackPanel Orientation="Horizontal" Margin="10">
            <CheckBox"></CheckBox>
            <TextBlock Text="{Binding Path=Number}"></TextBlock>
            <TextBlock Text=" - "></TextBlock>
            <TextBlock Text="{Binding Path=Name}"></TextBlock>
        </StackPanel>
    </DataTemplate>

所以我想要的基本上是一个简单的列表(带复选框),其中包含数字 - 名称。有没有一种方法可以直接在绑定部分将数字和名称连接起来?

4个回答

194

在.NET 3.5 SP1中有一个StringFormat属性,您可以使用它。并且您可以在这里找到有用的WPF绑定提示。如果这些都没有帮助,您可以随时编写自己的ValueConverter或自定义对象属性。

刚刚查了一下,您可以在多重绑定中使用StringFormat。在您的情况下,代码将类似于以下内容:

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

我不得不在格式化字符串前面加一个空格,否则Visual Studio就无法构建,但我认为你会找到解决方法的 :)

编辑
在StringFormat中需要使用空格来避免解析器将{0}视为实际绑定。其他替代方法:

<!-- use a space before the first format -->
<MultiBinding StringFormat=" {0} - {1}">

<!-- escape the formats -->
<MultiBinding StringFormat="\{0\} - \{1\}">

<!-- use {} before the first format -->
<MultiBinding StringFormat="{}{0} - {1}">

30
你可以使用{}代替空格,例如:StringFormat="{}{0} - {1}" - Bryan Anderson
7
您可以使用反斜杠来转义大括号:<MultiBinding StringFormat="{0} - {1}"> - hughdbrown
另外,缺失了 TextBlock 的关闭标签,因此总结一下评论如下: <TextBlock> <TextBlock.Text> <MultiBinding StringFormat="{}{0} - {1}"> <Binding Path="Number"/> <Binding Path="Name"/> </MultiBinding> </TextBlock.Text> </TextBlock> - Torben Junker Kjær
@PiRX 如果我想在“name”为空的情况下显示“number”,我该怎么做? - DasDas
很抱歉,@DasDas,由于我已经好几年没有使用WPF了,所以无法帮助你解决问题。有些东西你不再使用就会很快被遗忘,这真是有趣。 - PiRX
StringFormat扩展到其嵌套元素是否可以正常工作,而无需转义或遇到相同的问题? - jeromej

80

如果你想将动态值与静态文本连接起来,请尝试以下操作:

<TextBlock Text="{Binding IndividualSSN, StringFormat= '\{0\} (SSN)'}"/>

显示: 234-334-5566 (社会安全号码)


工具提示无法正常工作。 - CodingNinja
工具提示无法正常工作。 - undefined

10

请看我在代码中使用Run类的以下示例:

        <TextBlock x:Name="..." Width="..." Height="..."
            <Run Text="Area="/>
            <Run Text="{Binding ...}"/>
            <Run Text="sq.mm"/>
            <LineBreak/>
            <Run Text="Min Diameter="/>
            <Run Text="{Binding...}"/>
            <LineBreak/>
            <Run Text="Max Diameter="/>
            <Run Text="{Binding...}"/>
        </TextBlock >

3
你还可以使用可绑定的run。这是非常有用的,特别是当你想添加一些文本格式(颜色、字体加粗等)时。
<TextBlock>
   <something:BindableRun BoundText="{Binding Number}"/>
   <Run Text=" - "/>
   <something:BindableRun BoundText="{Binding Name}"/>
</TextBlock>

这里有一个原始的类:
这里有一些额外的改进。
这就是所有的代码。

public class BindableRun : Run
    {
        public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register("BoundText", typeof(string), typeof(BindableRun), new PropertyMetadata(new PropertyChangedCallback(BindableRun.onBoundTextChanged)));

        private static void onBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((Run)d).Text = (string)e.NewValue;
        }

        public String BoundText
        {
            get { return (string)GetValue(BoundTextProperty); }
            set { SetValue(BoundTextProperty, value); }
        }

        public BindableRun()
            : base()
        {
            Binding b = new Binding("DataContext");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(FrameworkElement), 1);
            this.SetBinding(DataContextProperty, b);
        }
    }

1
<Run Text="{Binding...}"/>?你能解释一下它的优点吗? - Felix Keil
3
这个答案写于10年前,当时Run不支持Text属性上的绑定,现在也没有任何区别。 - josh2112

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接