Элемент RichTextBlock

134

В Silverlight включена специализированная версия элемента RichTextBox, которая работает только в режиме чтения и называется RichTextBlock. Внутренняя структура и свойства отображения содержимого этих двух элементов почти аналогичны. Единственное отличие состоит в том, что RichTextBlock предназначен для совместной работы с одним или несколькими связанными элементами RichTextBlockOverflow, обеспечивающими гибкую компоновку содержимого.

Базовая идея довольно простая - с помощью RichTextBlock в комбинации с несколькими связанными RichTextBlockOverflow можно разбить длинный документ на несколько частей. Эти части можно расположить на странице произвольным способом, например разместить текст в нескольких колонках. Приложив еще немного усилий, можно разместить текст как в газете, в которой колонки и текст обтекают изображения и другие элементы компоновки.

В качестве примера рассмотрим следующий элемент RichTextBlock:

<RichTextBlock x:Name="richText"></RichTextBlock>

Если содержимого больше, чем поместится в область отображения RichTextBlock, не поместившийся текст будет отсечен. Однако посмотрим, что произойдет, если добавить на страницу элемент RichTextBlockOverflow:

<RichTextBlock x:Name="richText"></RichTextBlock>
   ...
<RichTextBlockOverflow x:Name="overflow1"/>

Свяжем элемент RichTextBlock с RichTextBlockOverflow с помощью свойства OverflowContentTarget и выражения связывания:

<RichTextBlock x:Name="richText"
       OverflowContentTarget="{Binding ElementName=overflow1}"></RichTextBlock>
   ...
<RichTextBlockOverflow x:Name="overflow1"/>

Теперь, если размеры элемента RichTextBlock ограничены и содержимого больше, чем в нем может поместиться, остаток перетекает в элемент RichTextBlockOverflow, который может находиться в любом месте этой же страницы. Для создания сложной компоновки можно использовать много элементов RichTextBlockOverflow. В каждом из них нужно использовать свойство OverflowContentTarget для связывания со следующим элементом в последовательности элементов.

Рассмотрим данную концепцию на примере простой страницы. Приведенная ниже разметка создает элемент Grid, состоящий из трех колонок. Левая колонка содержит элемент RichTextBlock. Вторая и третья колонки содержат элементы RichTextBlockOverflow, принимающие избыточное содержимое:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <RichTextBlock x:Name="richText" 
                       OverflowContentTarget="{Binding ElementName=overflow1}">
            ...
        </RichTextBlock>
        <RichTextBlockOverflow x:Name="overflow1" Grid.Column="1"
                               OverflowContentTarget="{Binding ElementName=overflow2}"/>
        <RichTextBlockOverflow x:Name="overflow2" Grid.Column="2"/>
</Grid>

Результат показан на рисунке ниже. Если страница достаточно большая, все содержимое поместится в левой колонке. Но если пользователь уменьшит размеры окна браузера, не поместившееся содержимое будет добавлено сначала во вторую, а затем — в третью колонку:

Перетекание текста в дополнительные колонки

Если содержимое не помещается и в последний элемент RichTextBlockOverflow, избыточное содержимое отсекается. К сожалению, простого способа исправления этого недостатка не существует. Если заключить RichTextBlock и RichTextBlockOverflow в область прокручивания ScrollViewer, первая колонка получит возможность увеличиваться, в результате чего вторая и третья колонки останутся пустыми. Для решения данной проблемы нужна более мощная модель потоковых документов, применяемая в WPF, но в Silverlight она не поддерживается.

При работе с перетекающим текстом главная точка взаимодействия с ним (как в разметке XAML, так и в коде C#) — элемент RichTextBlock. Коллекция RichTextBlock.Blocks используется для установки содержимого и манипулирования им (например, для форматирования). Элементы RichTextBlockOverflow управляют только местом отображения содержимого.

Умея создавать цепочку элементов RichTextBlockOverflow, можете подойти к задаче еще более творчески. Например, можете использовать более сложный элемент Grid для размещения элемента Image между элементами RichTextBlockOverflow.

Пройди тесты
Лучший чат для C# программистов