3

I have got multiple TextBlocks whose Text is inserted through DynamicResource. They are all set to TextWrapping="Wrap". But inside those Text-strings I have words which are not allowed to be split up. Those words must be kept as a whole word.

With hardcoded Text in Xaml it's quite easy solved via a TextBlock inside a Textblock:

<TextBlock TextWrapping="Wrap">
Example text with wrap and <TextBlock TextWrapping="NoWrap" Text=" example text without wrap"/
</TextBlock>

But this solution does not work when Text the is inserted through DynamicResource, because the text is not getting parsed.

How can I combine nowrap and wrap inside a DynamicResource Text without splitting it into multiple TextBlocks one after another?

PS: I have now created an example to demonstrate the behavior I would like (green) and the failed attempts (red, orange, darkred) of solving it:

<StackPanel HorizontalAlignment="Center" Width="80" Orientation="Vertical">
            <TextBlock TextWrapping="Wrap" Foreground="green">
                bla1 bla2 bla3 bla4 <TextBlock TextWrapping="NoWrap" Text="Together(en)"/> bla5 bla6 longWordWhichShouldBreak
            </TextBlock>
            <TextBlock TextWrapping="Wrap" Foreground="red">
                bla1 bla2 bla3 bla4 Together(en) bla5 bla6 longWordWhichShouldBreak
            </TextBlock>
            <TextBlock TextWrapping="Wrap" Foreground="orange">
                bla1 bla2 bla3 bla4&#160;Together(en)&#160;bla5 bla6 longWordWhichShouldBreak
            </TextBlock>
            <TextBlock TextWrapping="WrapWithOverflow" Foreground="DarkRed">
                bla1 bla2 bla3 bla4&#160;Together(en)&#160;bla5 bla6 longWordWhichShouldBreak
            </TextBlock>
        </StackPanel>

Result

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
CR500
  • 41
  • 6
  • 1
    Sounds like your so called "DynamicResource" is not suitable structured for usage in WPF. How about some preprocessing into a sequence of text chunks where each chunk has its display options? – grek40 Feb 28 '17 at 12:14
  • Yes preprocessing into multiple sequence of text, in nowrap and wrap pieces is a solution. But it's relatively costly. I thought that there is a better solution of keeping just a single word together in wrap textblock. – CR500 Feb 28 '17 at 12:20
  • Generally, you may have better luck with the `TextBlock.Inlines` property than the `TextBlock.Text` property. You can't expect the `Text` property to do anything else than just eating your text as... well text. – grek40 Feb 28 '17 at 12:30
  • Thank your for this hint with Inlines! But Inlines is not bindable and can not be injected with a DynamicResource I think. – CR500 Feb 28 '17 at 12:55
  • 1
    Uh, surprise... but the point is, when you write `` you use `Text`, but when you write `X` the `TextBlock.Inlines` collection is used, __not__ the `Text` property. So don't hope to emulate your written XAML without using the inlines. – grek40 Feb 28 '17 at 12:58

4 Answers4

2

Use NO-BREAK SPACE in your dynamic text. For example:

<TextBlock TextWrapping="Wrap">
        Example text with wrap and example text&#160;without&#160;wrap
</TextBlock>

You can replace space with this char in those parts that you need this behaviour:

  Replace(" ", System.Convert.ToChar(160))
rmojab63
  • 3,513
  • 1
  • 15
  • 28
  • Thank you. No-break space would be a good solution. Unfortunately it doesn't work: [Screenshot of no-break space xaml and window](http://666kb.com/i/dh38s0g1zt1hss3k8.png) – CR500 Feb 28 '17 at 06:54
  • This is how things work with ``TextWrapping="Wrap"``. Even if you use a long word, it will break it in order to wrap it in the available space. Use ``TextWrapping="WrapWithOverflow"`` and the result is similar to using ``TextBlock`` within ``TextBlock``,(i.e., the example in the question). – rmojab63 Feb 28 '17 at 09:42
1

Have you considered using 'WrapWithOverflow' instead of 'Wrap'? This will only break the line if a space appears.

You can then set the words that must appear together with dashes,e.g.- 'regular line and words-that-shouldn't-break'

Shtut
  • 1,397
  • 2
  • 14
  • 28
  • Thank you! Yes I have also tried WrapWithOverflow. The problem with this setting is that the text is partly standing out and therefore not visible (cut off). – CR500 Feb 28 '17 at 07:02
0

You should use Run:

<TextBlock>
    <Run Text={x:static SomeText} />
    <Run Text={x:static SomeNoWrapText}
         TextWrapping="NoWrap"/>
    <Run Text={x:static SomeMoreText} />
</TextBlock>
Omri Aviv
  • 126
  • 1
  • 3
  • Using run has the same effect as using textblock inside textblock. It does work in XAML-Code directly but it does not work when inserted through dynamic ressource. – CR500 Feb 28 '17 at 07:00
0

It's a bit much for a comment, but also not a complete answer.

Lets translate your example piece of XAML from all the implicit contents to a full qualified structure.

Your simplified XAML, using the implicit content properties and so on:

<TextBlock TextWrapping="Wrap" Foreground="green">
    bla1 bla2 bla3 bla4 <TextBlock TextWrapping="NoWrap" Text="Together(en)"/> bla5 bla6 longWordWhichShouldBreak
</TextBlock>

Equivalent actual structure:

<TextBlock TextWrapping="Wrap" Foreground="green">
    <TextBlock.Inlines>
        <Run Text="bla1 bla2 bla3 bla4 "/>
        <InlineUIContainer>
            <InlineUIContainer.Child>
                <TextBlock TextWrapping="NoWrap" Text="Together(en)"/>
            </InlineUIContainer.Child>
        </InlineUIContainer>
        <Run Text=" bla5 bla6 longWordWhichShouldBreak"/>
    </TextBlock.Inlines>
</TextBlock>

This should give you some idea about the complexity of what you have in your XAML. You can't archieve the same result by simply setting the Text property.

Currently I can't answer how to solve this issue, since DynamicResource is not enough information to start transforming into above structure.

You may want to have a look at this question: Data binding the TextBlock.Inlines

Community
  • 1
  • 1
grek40
  • 13,113
  • 1
  • 24
  • 50