Строковые элементы
122WPF --- Периферия WPF --- Строковые элементы
WPF предлагает большой набор строковых элементов, которые можно помещать в блочные или другие строковые элементы. Большинство из них довольно просты. Все они перечислены ниже.
- Run
Содержит обычный текст. Допускает применение форматирования, хотя обычно для этого используется элемент Span. Элементы Run часто создаются неявно (например, при добавлении текста в абзац)
- Span
Объединяет любое количество других строковых элементов. Обычно используется для особого форматирования части текста. Для этого элемент Run упаковывается в элемент Span, и задаются свойства элемента Span. (Можно просто поместить текст в элемент Span, a вложенный элемент Run будет создан автоматически.) Другая причина использования элемента Span — он позволяет легко найти и обработать конкретный фрагмент текста. Элемент Span аналогичен элементу <span> в языке HTML
- Bold, Italic и Underline
Применяют соответственно полужирное, курсивное и подчеркнутое форматирование. Эти элементы порождены от Span. Однако обычно лучше упаковать формируемый текст в элемент span, а затем с помощью свойства Span.Style указать стиль с нужным форматом. Тогда впоследствии можно будет легко изменять характеристики форматирования, не меняя разметку документа
- Hyperlink
Представляет ссылку, реагирующую на щелчок мыши, внутри потокового документа. В оконном приложении в ответ на событие Click можно выполнить действие (например, вывести другой документ). В страничном приложении можно использовать свойство NavigateUri, чтобы пользователь мог переходить к произвольной странице
- LineBreak
Добавляет разрыв строки в блочный элемент. Прежде чем использовать разрыв строки, подумайте: возможно, лучше использовать большие значение Margin или Padding, чтобы увеличить промежутки между элементами
- InlineUIContainer
Позволяет помещать элементы, не связанные с содержимым (наследники UIElement), туда, где должны быть строковые элементы (например, в элемент Paragraph). InlineUIContainer похож на BlockUIElement, но является строковым элементом, а не блочным
- Floater и Figure
Позволяют внедрять всплывающее окошко, в котором можно вывести важную информацию, рисунок или связанное содержимое (например, рекламные сообщения, ссылки, кодовые фрагменты и т.п.)
Добавление пробелов
Как правило, пробельные символы в XML сворачиваются. Поскольку XAML основан на языке XML, в нем действуют те же правила.
Таким образом, если вставить в содержимое несколько пробелов подряд, они будут преобразованы в один пробел. Это означает, что разметка
<Paragraph>привет всем</Paragraph>
эквивалентна следующей разметке:
<Paragraph>привет всем</Paragraph>
Обычно это поведение имеет смысл. Оно позволяет делать отступы в разметке документа с помощью символов разрыва строки и табуляции, не меняя способ интерпретации содержимого.
Знаки табуляции и разрывы строк обрабатываются так же, как и пробелы. Внутри содержимого они сворачиваются в один пробел, а по краям содержимого игнорируются.
Однако у этого правила есть одно исключение. Если пробел стоит перед строковым элементом, WPF сохраняет этот пробел. (А если перед ним несколько пробелов, WPF свернет их в один пробел.) Это означает, что можно написать следующую разметку:
<Paragraph>При встрече говорят <Bold>Привет</Bold></Paragraph>
Здесь пробел между строкой "При встрече говорят" и вложенным элементом Bold остается, что и требовалось. Однако если переписать разметку так, как показано ниже, пробел исчезнет:
<Paragraph>При встрече говорят<Bold> Привет</Bold></Paragraph>
В этом случае в пользовательском интерфейсе появится текст "При встрече говорятПривет". Между прочим, Visual Studio 2005 ошибочно игнорирует пробел в обоих примерах, если просматривать содержимое потокового документа в окне проектирования. Но в работающем приложении все станет на свои места.
Иногда бывает необходимо вставить пробел туда, где он обычно игнорируется, или включить последовательность пробелов. В этом случае понадобится атрибут xml:space со значением preserve, которое сообщает анализатору XML, что во вложенном содержимом нужно сохранять все пробельные символы:
<Paragraph xml:space="preserve">Это очень разреженный текст</Paragraph>
Это решение лучше, но оно не устраняет все проблемы. Теперь, когда синтаксический анализатор XML почтительно относится к пробельным символам, уже нельзя использовать разрывы строки и символы табуляции, чтобы сделать отступ в содержимом для облегчения чтения кода. В длинных абзацах это усложнит понимание разметки. (Естественно, проблемы не будет, если разметка потокового документа генерируется другим инструментом: тогда вам все равно, как выглядит преобразованная разметка XAML.)
Поскольку атрибут xml:space применим к любому элементу, с пробелами можно обращаться более выборочно. Например, следующая разметка сохраняет пробелы только во вложенном элементе Run:
<Paragraph>
<Run xml:space="preserve">Это очень разреженный</Run> текст
</Paragraph>
Элемент Floater
Элемент Floater (плавающее окошко) позволяет выделить часть содержимого из главного документа. По сути, эта часть помещается в "окошко", которое плавает где-то в вашем документе (обычно у одной из сторон документа). На рисунке ниже показан пример с одной строкой текста:
Для его создания нужно просто поместить элемент Floater где-нибудь в другом блочном элементе (например, в абзаце). Сам элемент Floater также может содержать один или более блочных элементов. Ниже показана разметка, использованная для создания этого примера:
<Style x:Key="FloaterStyle">
<Setter Property="Paragraph.FontSize" Value="30" ></Setter>
<Setter Property="Paragraph.FontStyle" Value="Italic" ></Setter>
<Setter Property="Paragraph.Foreground" Value="Green" ></Setter>
<Setter Property="Paragraph.Padding" Value="5"></Setter>
<Setter Property="Paragraph.Margin" Value="5,10,15,10"></Setter>
</Style>
...
<Paragraph>Прежде чем выяснить, что это за положительные заряды ...
<Floater Style="{StaticResource FloaterStyle}">
<Paragraph>Этот эффект называют эффектом Холла</Paragraph>
</Floater>
</Paragraph>
Как правило, потоковый документ расширяет плавающее окошко так, чтобы все содержимое как раз уместилось в одной строке, а если это невозможно — чтобы содержимое полностью заняло по ширине колонку в окне документа. (В данном примере имеется только одна колонка, поэтому Floater занимает окно документа по всей его ширине.)
Если вас это не устраивает, то с помощью свойства Width можно задать ширину в не зависящих от устройства единицах. А с помощью свойства HorizontalAlignment можно определить местоположение плавающего окна: по центру, слева или справа. Ниже показано, как можно создать плавающее окошко, расположенное слева:
<Floater Style="{StaticResource FloaterStyle}" Width="220" HorizontalAlignment="Left">
<Paragraph>Этот эффект называют эффектом Холла</Paragraph>
</Floater>
По умолчанию плавающее окошко, используемое для элемента Floater, является невидимым. Однако для него можно задать текстурированный фон (с помощью свойства Background) или рамку (с помощью свойств BorderBrush и BorderThickness), чтобы четко отделить его содержимое от остальной части документа. Можно также использовать свойство Margin, чтобы добавить промежуток между плавающим окошком и документом, и свойство Padding, чтобы добавить промежуток между краями окошка и его содержимым.
Как правило, свойства Background, BorderBrush, BorderThickness, Margin и Padding имеются только у блочных элементов. Но они определены и в классах Floater и Figure, которые представляют строковые элементы.
Элемент Floater можно применять и для вывода рисунков. Но, как ни странно, не существует элемента вывода потокового содержимого, предназначенного для этой задачи. Поэтому элемент Image придется применять вместе с элементом BlockUIContainer или InlineUIContainer.
Здесь есть один опасный момент. При вставке плавающего окошка, заключающего в себе изображение, потоковый документ предполагает, что рисунок должен быть по ширине таким же, как и вся колонка текста. Размер находящегося внутри элемента Image будет изменен, что может привести к возникновению проблем, если придется сильно уменьшить или увеличить растровое изображение.
С помощью свойства Image.Stretch можно запретить изменение размеров изображения, хотя в этом случае плавающее окошко все равно займет всю колонку по ширине — просто вокруг рисунка останутся пустые места. Единственным подходящим решением при внедрении растрового изображения в потоковый документ является указание фиксированных размеров плавающего окошка. После этого с помощью свойства Image.Stretch можно определить, как будет меняться размер изображения в этом окошке. Вот пример:
<Paragraph>
Это отличие состоит в том,
<Floater Width="140" Padding="5,0" HorizontalAlignment="Right">
<BlockUIContainer>
<Image Source="testimage.jpg"/>
</BlockUIContainer>
</Floater>
что в полупроводниках можно обнаружить электрический ток...
</Paragraph>
Результат показан на рис.
Обратите внимание, что изображение на самом деле находится в двух абзацах, но это не портит внешний вид документа. В потоковом документе текст обтекает все плавающие окошки.
Плавающее окошко с фиксированными размерами очень удобно при изменении масштаба документа. При этом изменяются и размеры плавающего окошка, после чего изображение внутри плавающего окошка может изменить свой размер (в зависимости от свойства Image.Stretch) и полностью заполнить плавающее окошко или разместиться в его центре.
Элемент Figure
Элемент Figure (рисунок) подобен Floater, однако он позволяет точнее управлять местоположением. Обычно используются плавающие окошки, которые дают WPF больше свободы в оформлении содержимого. Однако при работе со сложным документом и/или форматированием можно использовать именно рисунки, чтобы плавающие окошки не смещались при изменении размеров окна, или чтобы поместить окна в определенную позицию.
Итак, в чем же отличие класса Figure от класса Floater? Ниже описаны свойства, с которыми вам придется иметь дело. Здесь, однако, следует отметить, что многие из этих свойств (включая HorizontalAnchor, VerticalOffset и HorizontalOffset) не поддерживаются контейнером FlowDocumentScrollViewer, используемым для отображения потокового документа. Для них необходим один или несколько специальных контейнеров. Замените дескриптор FlowDocumentScrollViewer дескрипторами FlowDocumentReader, если вы хотите использовать свойства позиционирования рисунка.
- Width
Задает ширину рисунка. Размеры рисунка можно задавать точно так же, как и размеры плавающего окна: в не зависящих от устройства единицах. Кроме того, размеры рисунка можно задать относительно всего окна или текущей колонки. Например, в XAML можно написать "0.25 content", чтобы создать окошко с размером 25% от ширины окна или "2 Column", чтобы создать окошко, которое по ширине будет равно двум колонкам.
- Height
Задает высоту рисунка. Ее также задать можно задавать в не зависящих от устройства единицах. (Для сравнения: плавающее окошко выбирает для себя такую высоту, которая необходима, чтобы все содержимое уместилось при заданной ширине.) Если с помощью свойств Width и Height создать плавающее окно, которое окажется слишком маленьким, то часть содержимого будет отброшена
- HorizontalAnchor
Заменяет свойство HorizontalAlignment класса Floater. Но кроме трех эквивалентных параметров (ContentLeft, ContentRight и ContentCenter) включает также параметры позиционирования рисунка на текущей странице (например, PageCenter) или столбце (например, ColumnCenter)
- VerticalAnchor
Позволяет выровнять изображение по вертикали относительно текущей строки текста, текущей колонки или текущей страницы
- HorizontalOffset и VerticalOffset
Определяют выравнивание рисунка. Эти свойства позволяют сместить рисунок от его базовой позиции.
Например, при отрицательном значении VerticalOffset рисунок будет смещен вверх на указанное количество единиц. Если с помощью этих свойств сместить рисунок от края окна, то освободившееся место будет занято текстом. (Если нужно добавить свободное место без текста у одной стороны рисунка, воспользуйтесь свойством Figure.Padding.)
- WrapDirection
Определяет, как будет производиться обтекание текстом с одной стороны или с обеих сторон (с возможными пробелами) рисунка