TextBlock TextWrapping Wrap и NoWrap в сочетании и Text через DynamicResource

У меня есть несколько TextBlocks, текст которых вставлен через DynamicResource. Все они имеют значение TextWrapping = "Wrap". Но внутри этих текстовых строк у меня есть слова, которые нельзя разделять. Эти слова нужно сохранить как единое слово.

С жестко запрограммированным текстом в Xaml это довольно легко решить с помощью TextBlock внутри Textblock:

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

Но это решение не работает, когда Text the вставляется через DynamicResource, потому что текст не анализируется.

Как я могу объединить nowrap и wrap внутри текста DynamicResource, не разделяя его на несколько 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>

Результат


person CR500    schedule 27.02.2017    source источник
comment
Похоже, ваш так называемый DynamicResource не подходит для использования в WPF. Как насчет предварительной обработки последовательности фрагментов текста, где каждый фрагмент имеет свои параметры отображения?   -  person grek40    schedule 28.02.2017
comment
Да, предварительная обработка в несколько последовательностей текста, в частях nowrap и wrap - это решение. Но это относительно дорого. Я подумал, что есть лучшее решение - хранить только одно слово в текстовом блоке переноса.   -  person CR500    schedule 28.02.2017
comment
Как правило, вам может повезти больше со свойством TextBlock.Inlines, чем со свойством TextBlock.Text. Вы не можете ожидать, что свойство Text будет делать что-то еще, кроме как просто съесть ваш текст как ... ну, текст.   -  person grek40    schedule 28.02.2017
comment
Спасибо за подсказку с Inlines! Но я думаю, что Inlines не привязывается и не может быть введен с помощью DynamicResource.   -  person CR500    schedule 28.02.2017
comment
Сюрприз ... но суть в том, что когда вы пишете <TextBlock Text="X"/>, вы используете Text, но когда вы пишете <TextBlock>X</TextBlock>, используется коллекция TextBlock.Inlines, не свойство Text. Так что не надейтесь подражать написанному вами XAML без использования inlines.   -  person grek40    schedule 28.02.2017


Ответы (4)


Используйте NO-BREAK SPACE в динамическом тексте. Например:

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

Вы можете заменить пробел этим символом в тех частях, где вам нужно это поведение:

  Replace(" ", System.Convert.ToChar(160))
person Ron    schedule 27.02.2017
comment
Спасибо. Непрерывное пространство было бы хорошим решением. К сожалению, это не работает: Снимок экрана без прерывания пространства xaml и окна - person CR500; 28.02.2017
comment
Вот как все работает с TextWrapping="Wrap". Даже если вы используете длинное слово, оно разорвет его, чтобы заключить в доступное место. Используйте TextWrapping="WrapWithOverflow", и результат будет аналогичен использованию TextBlock в _4 _ (т.е. пример в вопросе). - person Ron; 28.02.2017

Думали ли вы об использовании "WrapWithOverflow" вместо "Wrap"? Это приведет к разрыву строки только в том случае, если появится пробел.

Затем вы можете установить слова, которые должны отображаться вместе с тире, например, «обычная строка и слова, которые не должны разрываться».

person Shtut    schedule 27.02.2017
comment
Спасибо! Да, я тоже пробовал WrapWithOverflow. Проблема с этой настройкой заключается в том, что текст частично выделяется и поэтому не виден (обрезан). - person CR500; 28.02.2017

Вы должны использовать Run:

<TextBlock>
    <Run Text={x:static SomeText} />
    <Run Text={x:static SomeNoWrapText}
         TextWrapping="NoWrap"/>
    <Run Text={x:static SomeMoreText} />
</TextBlock>
person Omri Aviv    schedule 27.02.2017
comment
Использование run имеет тот же эффект, что и использование текстового блока внутри текстового блока. Он действительно работает в XAML-коде напрямую, но не работает при вставке через динамический ресурс. - person CR500; 28.02.2017

Это многовато для комментария, но и не исчерпывающий ответ.

Давайте переведем ваш пример фрагмента 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 недостаточно информации, чтобы начать преобразование в указанную выше структуру.

Возможно, вы захотите взглянуть на этот вопрос: Связывание данных TextBlock.Inlines

person grek40    schedule 28.02.2017