文本块文本换行包括换行和不换行并通过DynamicResource实现文本。

3
我有多个TextBlock,它们的文本是通过DynamicResource插入的。它们都设置为TextWrapping="Wrap"。但在这些文本字符串中,我有一些不允许被分割的单词,这些单词必须作为整个单词保留。
通过Xaml中硬编码的文本,可以通过TextBlock内部的Textblock轻松解决此问题:
<TextBlock TextWrapping="Wrap">
Example text with wrap and <TextBlock TextWrapping="NoWrap" Text=" example text without wrap"/
</TextBlock>

但是,当通过DynamicResource插入文本时,这种解决方案不起作用,因为文本没有被解析。

我如何在DynamicResource Text中结合nowrap和wrap,而不将其拆分成多个TextBlocks?

PS:我现在创建了一个示例来演示我想要的行为(绿色)以及解决它的失败尝试(红色,橙色,深红色):

<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


1
听起来你所谓的“DynamicResource”并不适合在WPF中使用。不妨对其进行一些预处理,将其转换为一系列文本块,每个块都有其显示选项。 - grek40
是的,将预处理成多个文本序列,分别在不换行和换行块中是一个解决方案。但这相对来说比较昂贵。我认为,在包装的文本块中只保留一个单词在一起的更好的解决方案。 - CR500
通常情况下,您使用TextBlock.Inlines属性要比使用TextBlock.Text属性更好。您不能期望Text属性除了将文本作为文本处理外还能做其他事情。 - grek40
感谢您提供有关Inlines的提示!但是我认为Inlines无法绑定,也无法使用DynamicResource注入。 - CR500
1
哦,有点惊喜...但是重点是,当你写<TextBlock Text="X"/>时,你使用的是Text属性,但是当你写<TextBlock>X</TextBlock>时,使用的是TextBlock.Inlines集合,而不是Text属性。因此,如果不使用inlines,就不要指望能够模拟你编写的XAML。 - grek40
4个回答

3

在您的动态文本中使用不间断空格。例如:

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

在需要这种行为的部分,您可以使用此字符替换空格:

  Replace(" ", System.Convert.ToChar(160))

谢谢。不间断空格本来是一个好的解决方案。但不幸的是它不起作用:不间断空格 XAML 和窗口的截图 - CR500
这就是使用“TextWrapping =”Wrap“”的工作原理。即使您使用了一个长单词,它也会将其分解以便在可用空间中进行换行。使用“TextWrapping =”WrapWithOverflow“”,结果类似于在“TextBlock”内部使用“TextBlock”(即问题中的示例)。 - rmojab63

1
您考虑过使用“WrapWithOverflow”而不是“Wrap”吗? 这将仅在出现空格时换行。
然后,您可以使用破折号设置必须连在一起的单词,例如“常规行和不应该断开的单词”。

谢谢!是的,我也尝试过WrapWithOverflow。这种设置的问题在于,文本部分会突出显示,因此无法看到(被截断了)。 - CR500

0

你应该使用“运行”:

<TextBlock>
    <Run Text={x:static SomeText} />
    <Run Text={x:static SomeNoWrapText}
         TextWrapping="NoWrap"/>
    <Run Text={x:static SomeMoreText} />
</TextBlock>

使用run的效果与在textblock内部使用textblock相同。它可以直接在XAML代码中工作,但是通过动态资源插入时却无法工作。 - CR500

0

这有点过于冗长了,但也不是完整的答案。

让我们将你的XAML例子从所有隐式内容翻译成一个完全合格的结构。

你简化后的XAML,使用了隐式内容属性等:

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

等效的实际结构:

<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>

这应该让你对你的XAML中所涉及的复杂性有一些了解。仅仅设置Text属性是无法达到相同的效果的。

目前我无法回答如何解决这个问题,因为DynamicResource不足以开始转换成上述结构。

你可能想看一下这个问题:Data binding the TextBlock.Inlines


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