WPF TextBlock与<linebreak> </linebreak>绑定

时间:2010-04-05 19:12:22

标签: wpf wpf-controls

我在ControlTemplate中有如下TextBlock绑定。

<TextBlock Grid.Column="1" VerticalAlignment="Center"
 FontSize="16" FontFamily="Arial" FontWeight="Bold"
 Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=ButtonText}">
</TextBlock>

当我按如下方式设置ButtonText时,它不起作用。它不会单独显示。

ButtonText="Change<LineBreak/> Casette"

如何解决这个问题?感谢您的帮助,请提供示例代码。

2 个答案:

答案 0 :(得分:13)

TextBlock显示其Inlines属性的内容。 Text属性仅为方便而存在(尽管它很重要):如果设置Text属性,TextBlock将创建Run,将其内容设置为您提供的字符串,并将其保存在Inlines集合中。

在XAML中设置TextBlock元素的内容时,XamlReader会直接填充Inlines集合,而不是Text属性。它将文本节点解析为Run个对象,以及XAML常用的元素。所以这个:

<TextBlock>
   Line1<LineBreak/>Line2
</TextBlock>

被视为实际上是这样的:

<TextBlock>
   <Run>Line1</Run>
   <LineBreak/>
   <Run>Line2</Run>
</TextBlock>

请注意,如果您尝试明确设置Text属性:

<TextBlock>
   <TextBlock.Text>
      Line1<LineBreak/>Line2
   </TextBlock.Text>
</TextBlock>

您将获得异常,因为XamlReader将尝试创建LineBreak对象,而Text属性只能包含字符串。

您的绑定无法按照您希望的方式工作,因为它明确地将Text属性设置为字符串。这不会被解析为XAML(也是好事)。所以在TextBlock中显示的是该字符串的内容。

所以基本上有两种方法可以完成你想要完成的任务。在你的情况下,你可能只是在字符串中嵌入换行符。

但是如果你是从XAML那里做的话,这比看起来更棘手。因为XAML是XML,而XML对空白做了一些有趣的事情。如果使用XML字符实体在属性中明确设置它,例如:

,则可以
<TextBlock Text="Line 1&#x0d;&#x0a;Line 2"/>

但是,如果你这样做,这将无效:

<TextBlock>
   <TextBlock.Text>
      Line 1&#x0d;&#x0a;Line 2
   </TextBlock.Text>
</TextBlock>

因为XML解析器规范化元素内容中的空白。那个CR / LF对变成了一个单独的空间,这就是进入text属性的东西。

如果您正在使用绑定,则无需担心任何此类XML内容(除非您绑定到XML文档的内容!)。您只需将\r\n放入属性值即可。

其他方法是直接填充TextBlock的{​​{1}}属性。但是你不能通过绑定来做到这一点,因为Inlines不是依赖属性 - 事实上,它是只读的,你只能通过调用它Inlines或{{1}来填充它。方法。

答案 1 :(得分:3)

我用这段代码来获得你想要的东西。这是XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="1" VerticalAlignment="Center"
           FontSize="16" FontFamily="Arial" FontWeight="Bold"
           Text="{Binding Path=ButtonText}">
    </TextBlock>
</Grid>

这就是背后的代码。为了使示例更简单,我不创建ViewModel类:

    public Window1()
    {
        InitializeComponent();
        DataContext = this;
        ButtonText = "Change\r\nCasette";
    }


    public string ButtonText
    {
        get { return (string)GetValue(ButtonTextProperty); }
        set { SetValue(ButtonTextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ButtonText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ButtonTextProperty =
        DependencyProperty.Register("ButtonText", typeof(string), typeof(Window1), new UIPropertyMetadata(""));