Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF TextBlock binding with <LineBreak/>

I have a TextBlock binding as follows in my ControlTemplate.

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

When I set ButtonText as follows with , it doesn't work. It doesn't display in separate line.

ButtonText="Change<LineBreak/> Casette"

How to fix this? Appreciate your help, please provide me with sample code.

like image 740
codematrix Avatar asked Apr 05 '10 19:04

codematrix


People also ask

How do I wrap text in TextBlock WPF?

In WPF, the Label control does not support text wrapping. If you need a label that wraps contents across multiple lines, you can use a TextBlock control. Place a TextBlock control inside a Label and apply wrapping on TextBlock.

How do I create a line break in TextBlock WPF?

Adding Line Breaks Sometimes you will want to insert a line break within a TextBlock. You can do this with a LineBreak inline, added as an XAML element within the text. A new line will be started at the position of this element.

How to break line in XAML?

XAML attributes of type String may contain any special characters, as long as those are referenced as hex-codes. For example, a simple line break ( \n ) would be represented as &#x0a; , for \r\n you'd use &#x0d;&#x0a; and so on.

How to add a newline in XAML?

In XAML , If you want to add the line break or newline within the string attribute of the TextBlock's Text property , you can use the hexidecimal encoded value &#x0a; which represents the line feed.


1 Answers

A TextBlock displays the contents of its Inlines property. The Text property exists only as a convenience (though it's a significant one): if you set the Text property, the TextBlock will create a Run, set its content to the string you've provided, and save it in the Inlines collection.

When you set the content of a TextBlock element in XAML, the XamlReader populates the Inlines collection directly rather than through the Text property. It parses text nodes into Run objects, and elements as usual for XAML. So this:

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

is treated as though it were actually this:

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

Note, by the way, that if you try to set the Text property explicitly:

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

you'll get an exception, because the XamlReader will try to create a LineBreak object, and the Text property can only contain a string.

Your binding isn't working the way you want it to because it's explicitly setting the Text property to a string. This doesn't get parsed as XAML (and good thing, too). And so what's displaying in the TextBlock is the content of that string.

So there are basically two ways to accomplish what you're trying to accomplish. In your case, you probably can just get away with embedding a newline into the string.

But this is trickier than it looks if you're doing it from XAML. Because XAML is XML, and XML does some funny things to whitespace. You're OK if you set it explicitly in an attribute using XML character entities, e.g.:

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

But that won't work if you do it this way:

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

because the XML parser normalizes whitespace in element content. That CR/LF pair gets turned into a single space, and that's what gets into the text property.

If you're using binding, you don't need to worry about any of this XML stuff (unless you're binding to the contents of an XML document!). You can just put \r\n into the property value.

The other way to do this is to directly populate the TextBlock's Inlines property. But you can't do this via binding, since Inlines isn't a dependency property - in fact, it's read-only, and you can only populate it by calling its Add or AddRange methods.

like image 152
Robert Rossney Avatar answered Sep 17 '22 16:09

Robert Rossney