Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Документы потока предназначены для оптимизации просмотра и удобства чтения. Вместо того чтобы быть закрепленными в одном предопределенном макете, поточные документы динамически настраивают и перераспределяют свое содержимое на основе переменных времени выполнения, таких как размер окна, разрешение устройства и пользовательские предпочтения. Кроме того, документы потока предлагают расширенные функции документа, такие как разбиение на страницы и столбцы. В этом разделе представлены общие сведения о документах потока и их создании.
Что такое документ потока
Документ потока предназначен для изменения содержимого в зависимости от размера окна, разрешения устройства и других переменных среды. Кроме того, документы потока имеют ряд встроенных функций, включая поиск, режимы просмотра, которые оптимизируют удобочитаемость, а также возможность изменять размер и внешний вид шрифтов. Документы потока лучше всего используются, когда удобство чтения является основным сценарием потребления документов. Напротив, фиксированные документы предназначены для статической презентации. Документы с фиксированной разметкой полезны, если точное воспроизведение исходного содержимого является критичным. Дополнительные сведения о различных типах документов см. в Материалы на WPF.
На следующем рисунке показан пример документа потока, просматриваемого в нескольких окнах различных размеров. По мере изменения области отображения содержимое перераспределяется, чтобы лучше использовать доступное пространство.
Как показано на рисунке выше, содержимое потока может включать множество компонентов, включая абзацы, списки, изображения и многое другое. Эти компоненты соответствуют элементам разметки и объектам в процедурном коде. Далее мы рассмотрим эти классы в разделе "Связанные с потоком классы " этого обзора. Теперь ниже приведен простой пример кода, который создает документ потока, состоящий из абзаца с некоторым полужирным текстом и списком.
<!-- This simple flow document includes a paragraph with some
bold text in it and a list. -->
<FlowDocumentReader xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FlowDocument>
<Paragraph>
<Bold>Some bold text in the paragraph.</Bold>
Some text that is not bold.
</Paragraph>
<List>
<ListItem>
<Paragraph>ListItem 1</Paragraph>
</ListItem>
<ListItem>
<Paragraph>ListItem 2</Paragraph>
</ListItem>
<ListItem>
<Paragraph>ListItem 3</Paragraph>
</ListItem>
</List>
</FlowDocument>
</FlowDocumentReader>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class SimpleFlowExample : Page
{
public SimpleFlowExample()
{
Paragraph myParagraph = new Paragraph();
// Add some Bold text to the paragraph
myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));
// Add some plain text to the paragraph
myParagraph.Inlines.Add(new Run(" Some text that is not bold."));
// Create a List and populate with three list items.
List myList = new List();
// First create paragraphs to go into the list item.
Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem 1"));
Paragraph paragraphListItem2 = new Paragraph(new Run("ListItem 2"));
Paragraph paragraphListItem3 = new Paragraph(new Run("ListItem 3"));
// Add ListItems with paragraphs in them.
myList.ListItems.Add(new ListItem(paragraphListItem1));
myList.ListItems.Add(new ListItem(paragraphListItem2));
myList.ListItems.Add(new ListItem(paragraphListItem3));
// Create a FlowDocument with the paragraph and list.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
myFlowDocument.Blocks.Add(myList);
// Add the FlowDocument to a FlowDocumentReader Control
FlowDocumentReader myFlowDocumentReader = new FlowDocumentReader();
myFlowDocumentReader.Document = myFlowDocument;
this.Content = myFlowDocumentReader;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class SimpleFlowExample
Inherits Page
Public Sub New()
Dim myParagraph As New Paragraph()
' Add some Bold text to the paragraph
myParagraph.Inlines.Add(New Bold(New Run("Some bold text in the paragraph.")))
' Add some plain text to the paragraph
myParagraph.Inlines.Add(New Run(" Some text that is not bold."))
' Create a List and populate with three list items.
Dim myList As New List()
' First create paragraphs to go into the list item.
Dim paragraphListItem1 As New Paragraph(New Run("ListItem 1"))
Dim paragraphListItem2 As New Paragraph(New Run("ListItem 2"))
Dim paragraphListItem3 As New Paragraph(New Run("ListItem 3"))
' Add ListItems with paragraphs in them.
myList.ListItems.Add(New ListItem(paragraphListItem1))
myList.ListItems.Add(New ListItem(paragraphListItem2))
myList.ListItems.Add(New ListItem(paragraphListItem3))
' Create a FlowDocument with the paragraph and list.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
myFlowDocument.Blocks.Add(myList)
' Add the FlowDocument to a FlowDocumentReader Control
Dim myFlowDocumentReader As New FlowDocumentReader()
myFlowDocumentReader.Document = myFlowDocument
Me.Content = myFlowDocumentReader
End Sub
End Class
End Namespace
На рисунке ниже показано, как выглядит фрагмент кода.
В этом примере элемент FlowDocumentReader управления используется для размещения содержимого потока. Дополнительные сведения о элементах управления размещением содержимого потока см. в разделе "Типы документов потока ". Paragraph, List, ListItemи Bold элементы используются для управления форматированием содержимого на основе их порядка в разметке. Например, элемент Bold охватывает только часть текста в абзаце; в результате только эта часть текста становится полужирной. Если вы использовали HTML, это будет знакомо вам.
Как показано на приведенном выше рисунке, существует несколько функций, встроенных в поток документов:
Поиск. Позволяет пользователю выполнять полнотекстовый поиск всего документа.
Режим просмотра: Пользователь может выбрать предпочтительный режим, включая просмотр по одной странице, просмотр по две страницы (формат чтения книги) и режим непрерывной прокрутки. Дополнительные сведения об этих режимах просмотра см. в FlowDocumentReaderViewingMode.
Элементы управления навигацией по страницам: если режим просмотра документа использует страницы, элементы управления навигацией страницы включают кнопку, чтобы перейти на следующую страницу (стрелку вниз) или предыдущую страницу (стрелка вверх), а также индикаторы для текущего номера страницы и общего количества страниц. Пролистывание страниц также можно выполнить с помощью клавиш со стрелками клавиатуры.
Масштаб: элементы управления масштабированием позволяют пользователю увеличивать или уменьшать масштаб, щелкнув кнопки плюса или минуса соответственно. Элементы управления масштабированием также включают ползунок для настройки уровня масштабирования. Дополнительные сведения см. в разделе Zoom.
Эти параметры можно изменить в зависимости от элемента управления, используемого для размещения содержимого потока. В следующем разделе описаны различные элементы управления.
Типы документов потока
Отображение и внешний вид содержимого документа потока зависят от того, какой объект используется для его размещения. Существует четыре элемента управления, поддерживающие просмотр содержимого потока: FlowDocumentReader, FlowDocumentPageViewer, RichTextBoxи FlowDocumentScrollViewer. Эти элементы управления кратко описаны ниже.
Замечание
FlowDocument требуется для прямого размещения содержимого потока, поэтому все эти элементы управления просмотра используют FlowDocument для возможности размещения содержимого потока.
Читатель потокового документа
FlowDocumentReader включает функции, позволяющие пользователю динамически выбирать между различными режимами просмотра, включая режим отдельной страницы (по одной странице), двухстраничный режим (формат чтения книг) и режим непрерывной прокрутки. Дополнительные сведения об этих режимах просмотра см. в FlowDocumentReaderViewingMode. Если вам не нужна возможность динамически переключаться между различными режимами просмотра, FlowDocumentPageViewer и FlowDocumentScrollViewer предоставляют облегчённые средства просмотра контента, зафиксированные в определённом режиме просмотра.
FlowDocumentPageViewer и FlowDocumentScrollViewer
FlowDocumentPageViewer отображает содержимое в режиме просмотра по одной странице за раз, в то время как FlowDocumentScrollViewer отображает содержимое в режиме непрерывной прокрутки. И FlowDocumentPageViewer, и FlowDocumentScrollViewer зафиксированы в определенном режиме просмотра. Сравните с FlowDocumentReader, которая включает функции, которые позволяют пользователю динамически выбирать между различными режимами просмотра (как указано в перечислении FlowDocumentReaderViewingMode), за счет более интенсивного использования ресурсов, чем FlowDocumentPageViewer или FlowDocumentScrollViewer.
По умолчанию вертикальная полоса прокрутки всегда отображается, а горизонтальная полоса прокрутки становится видимой при необходимости. Пользовательский интерфейс по умолчанию для FlowDocumentScrollViewer не включает панель инструментов; однако свойство IsToolBarVisible можно использовать для включения встроенной панели инструментов.
Поле форматированного текста
Вы используете RichTextBox , когда вы хотите разрешить пользователю изменять содержимое потока. Например, если вы хотите создать редактор, позволяющий пользователю управлять такими вещами, как таблицы, курсивное и полужирное форматирование и т. д., вы будете использовать .RichTextBox Дополнительные сведения см. в разделе "Обзор RichTextBox ".
Замечание
Содержимое потока внутри RichTextBox ведёт себя не так, как содержимое потока, находящееся в других элементах управления. Например, в RichTextBox нет столбцов и, поэтому, нет поведения автоматического изменения размера. Кроме того, обычно встроенные функции содержимого потока, такие как поиск, режим просмотра, навигация по страницам и масштабирование, недоступны в пределах RichTextBox.
Создание потокового содержимого
Содержимое потока может быть сложным, состоящим из различных элементов, включая текст, изображения, таблицы и даже UIElement производные классы, такие как элементы управления. Чтобы понять, как создать сложное содержимое потока, важны следующие моменты:
Классы, связанные с потоком: каждый класс, используемый в содержимом потока, имеет определенную цель. Кроме того, иерархическое отношение между классами потоков помогает понять, как они используются. Например, классы, производные от Block, используются для хранения других объектов, а классы, производные от Inline, содержат отображаемые объекты.
Схема содержимого: документ потока может требовать существенного количества вложенных элементов. Схема содержимого указывает возможные связи родительских и дочерних элементов.
В следующих разделах подробно рассматриваются все эти области.
Классы, связанные с потоком
На схеме ниже показаны объекты, наиболее часто используемые в контексте поточного контента.
Для потокового содержимого существуют две важные категории:
Классы, производные от блоков: также называются "Блочные элементы содержимого" или просто "Блочные элементы". Элементы, наследуемые от Block, можно использовать для группировки под общим родительским элементом или для применения общих атрибутов к группе.
Встроенные классы: также называемые "встроенные элементы содержимого" или просто "встроенные элементы". Элементы, наследуемые от Inline них, содержатся в блок-элементе или другом встроенном элементе. Встроенные элементы часто используются в качестве прямого контейнера содержимого, отображаемого на экране. Например, элемент Paragraph (Block Element) может содержать Run (встроенный элемент), но Run фактически содержит текст, отображаемый на экране.
Каждый класс в этих двух категориях кратко описан ниже.
Классы, производные от блоков
абзац
Paragraph обычно используется для группировки содержимого в абзац. Самый простой и наиболее распространенный способ использования абзаца — создание абзаца текста.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Some paragraph text.
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ParagraphExample : Page
{
public ParagraphExample()
{
// Create paragraph with some text.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(new Run("Some paragraph text."));
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class ParagraphExample
Inherits Page
Public Sub New()
' Create paragraph with some text.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(New Run("Some paragraph text."))
' Create a FlowDocument and add the paragraph to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
Однако вы также можете включать другие встроенные элементы, как вы увидите ниже.
Раздел
Section используется только для содержания других Block-производных элементов. Он не применяет форматирование по умолчанию к элементам, которые он содержит. Однако все значения свойств, заданные для Section, применяются к его дочерним элементам. Раздел позволяет программно выполнять итерацию по дочерней коллекции. Section используется аналогично тегу <DIV> в HTML.
В приведенном ниже примере три абзаца определены в рамках одного Section. Раздел имеет Background значение свойства Red, поэтому цвет фона абзацев также красный.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- By default, Section applies no formatting to elements contained
within it. However, in this example, the section has a Background
property value of "Red", therefore, the three paragraphs (the block)
inside the section also have a red background. -->
<Section Background="Red">
<Paragraph>
Paragraph 1
</Paragraph>
<Paragraph>
Paragraph 2
</Paragraph>
<Paragraph>
Paragraph 3
</Paragraph>
</Section>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class SectionExample : Page
{
public SectionExample()
{
// Create three paragraphs
Paragraph myParagraph1 = new Paragraph(new Run("Paragraph 1"));
Paragraph myParagraph2 = new Paragraph(new Run("Paragraph 2"));
Paragraph myParagraph3 = new Paragraph(new Run("Paragraph 3"));
// Create a Section and add the three paragraphs to it.
Section mySection = new Section();
mySection.Background = Brushes.Red;
mySection.Blocks.Add(myParagraph1);
mySection.Blocks.Add(myParagraph2);
mySection.Blocks.Add(myParagraph3);
// Create a FlowDocument and add the section to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(mySection);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class SectionExample
Inherits Page
Public Sub New()
' Create three paragraphs
Dim myParagraph1 As New Paragraph(New Run("Paragraph 1"))
Dim myParagraph2 As New Paragraph(New Run("Paragraph 2"))
Dim myParagraph3 As New Paragraph(New Run("Paragraph 3"))
' Create a Section and add the three paragraphs to it.
Dim mySection As New Section()
mySection.Background = Brushes.Red
mySection.Blocks.Add(myParagraph1)
mySection.Blocks.Add(myParagraph2)
mySection.Blocks.Add(myParagraph3)
' Create a FlowDocument and add the section to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(mySection)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
BlockUIContainer
BlockUIContainer позволяет внедрять элементы UIElement (т. е. Button) в потоковое содержимое, полученное из блоков. InlineUIContainer (см. ниже) используется для внедрения UIElement элементов в потоковое содержимое инлайн-типа. BlockUIContainer и InlineUIContainer важны, так как нет другого способа использовать UIElement в содержимом потока, если оно не содержится в одном из этих двух элементов.
В следующем примере показано, как использовать BlockUIContainer элемент для размещения UIElement объектов в содержимом потока.
<FlowDocument ColumnWidth="400">
<Section Background="GhostWhite">
<Paragraph>
A UIElement element may be embedded directly in flow content
by enclosing it in a BlockUIContainer element.
</Paragraph>
<BlockUIContainer>
<Button>Click me!</Button>
</BlockUIContainer>
<Paragraph>
The BlockUIContainer element may host no more than one top-level
UIElement. However, other UIElements may be nested within the
UIElement contained by an BlockUIContainer element. For example,
a StackPanel can be used to host multiple UIElement elements within
a BlockUIContainer element.
</Paragraph>
<BlockUIContainer>
<StackPanel>
<Label Foreground="Blue">Choose a value:</Label>
<ComboBox>
<ComboBoxItem IsSelected="True">a</ComboBoxItem>
<ComboBoxItem>b</ComboBoxItem>
<ComboBoxItem>c</ComboBoxItem>
</ComboBox>
<Label Foreground ="Red">Choose a value:</Label>
<StackPanel>
<RadioButton>x</RadioButton>
<RadioButton>y</RadioButton>
<RadioButton>z</RadioButton>
</StackPanel>
<Label>Enter a value:</Label>
<TextBox>
A text editor embedded in flow content.
</TextBox>
</StackPanel>
</BlockUIContainer>
</Section>
</FlowDocument>
На следующем рисунке показано, как отрисовывается этот пример:
Список
List используется для создания маркированного или числового списка. Задайте для свойства MarkerStyle значение перечисления TextMarkerStyle, чтобы определить стиль списка. В приведенном ниже примере показано, как создать простой список.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<List>
<ListItem>
<Paragraph>
List Item 1
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
List Item 2
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
List Item 3
</Paragraph>
</ListItem>
</List>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ListExample : Page
{
public ListExample()
{
// Create three paragraphs
Paragraph myParagraph1 = new Paragraph(new Run("List Item 1"));
Paragraph myParagraph2 = new Paragraph(new Run("List Item 2"));
Paragraph myParagraph3 = new Paragraph(new Run("List Item 3"));
// Create the ListItem elements for the List and add the
// paragraphs to them.
ListItem myListItem1 = new ListItem();
myListItem1.Blocks.Add(myParagraph1);
ListItem myListItem2 = new ListItem();
myListItem2.Blocks.Add(myParagraph2);
ListItem myListItem3 = new ListItem();
myListItem3.Blocks.Add(myParagraph3);
// Create a List and add the three ListItems to it.
List myList = new List();
myList.ListItems.Add(myListItem1);
myList.ListItems.Add(myListItem2);
myList.ListItems.Add(myListItem3);
// Create a FlowDocument and add the section to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myList);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class ListExample
Inherits Page
Public Sub New()
' Create three paragraphs
Dim myParagraph1 As New Paragraph(New Run("List Item 1"))
Dim myParagraph2 As New Paragraph(New Run("List Item 2"))
Dim myParagraph3 As New Paragraph(New Run("List Item 3"))
' Create the ListItem elements for the List and add the
' paragraphs to them.
Dim myListItem1 As New ListItem()
myListItem1.Blocks.Add(myParagraph1)
Dim myListItem2 As New ListItem()
myListItem2.Blocks.Add(myParagraph2)
Dim myListItem3 As New ListItem()
myListItem3.Blocks.Add(myParagraph3)
' Create a List and add the three ListItems to it.
Dim myList As New List()
myList.ListItems.Add(myListItem1)
myList.ListItems.Add(myListItem2)
myList.ListItems.Add(myListItem3)
' Create a FlowDocument and add the section to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myList)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
Замечание
List — единственный элемент потока, использующий ListItemCollection для управления дочерними элементами.
таблица
Table используется для создания таблицы. Table аналогичен элементу Grid , но он имеет больше возможностей и, следовательно, требует больше ресурсов. Так как Grid это UIElement, он не может использоваться в потоковом содержании, если он не содержится в BlockUIContainer или InlineUIContainer. Дополнительные сведения см. в разделе Table.
Классы с производными внутри строки
Беги
Run используется для хранения неформатированного текста. Возможно, Run объекты будут широко использоваться в содержимом потока. Однако в разметке элементы Run не обязаны использоваться явно. Run требуется использовать при создании или управлении документами потока с помощью кода. Например, в приведенной ниже разметке первый Paragraph указывает Run элемент явным образом, а второй — нет. Оба абзаца создают одинаковые выходные данные.
<Paragraph>
<Run>Paragraph that explicitly uses the Run element.</Run>
</Paragraph>
<Paragraph>
This Paragraph omits the Run element in markup. It renders
the same as a Paragraph with Run used explicitly.
</Paragraph>
Замечание
Начиная с .NET Framework 4, свойство Text объекта Run является зависимым свойством. Свойство можно привязать Text к источнику данных, например TextBlock. Свойство Text полностью поддерживает одностороннюю привязку. Свойство Text также поддерживает двусторонняя привязка, за исключением RichTextBox. Пример см. в разделе Run.Text.
Интервал
Span группирует другие встроенные элементы содержимого вместе. К содержимому в элементе Span не применяется внутренняя отрисовка. Однако элементы, наследующие от Span, включая Hyperlink, Bold, Italic и Underline, применяют форматирование к тексту.
Ниже приведен пример использования Span для хранения встроенного содержимого, включая текст, элемент Bold и элемент Button.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Text before the Span. <Span Background="Red">Text within the Span is
red and <Bold>this text is inside the Span-derived element Bold.</Bold>
A Span can contain more then text, it can contain any inline content. For
example, it can contain a
<InlineUIContainer>
<Button>Button</Button>
</InlineUIContainer>
or other UIElement, a Floater, a Figure, etc.</Span>
</Paragraph>
</FlowDocument>
На следующем снимке экрана показано, как отображается этот пример.
InlineUIContainer
InlineUIContainer позволяет встраивать элементы UIElement (такие как элемент управления Button) в элемент содержания Inline. Этот элемент является встроенным эквивалентом BlockUIContainer описанному выше. Ниже представлен пример, который использует InlineUIContainer для вставки Button встроенно в Paragraph.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Text to precede the button...
<!-- Set the BaselineAlignment property to "Bottom"
so that the Button aligns properly with the text. -->
<InlineUIContainer BaselineAlignment="Bottom">
<Button>Button</Button>
</InlineUIContainer>
Text to follow the button...
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class InlineUIContainerExample : Page
{
public InlineUIContainerExample()
{
Run run1 = new Run(" Text to precede the button... ");
Run run2 = new Run(" Text to follow the button... ");
// Create a new button to be hosted in the paragraph.
Button myButton = new Button();
myButton.Content = "Click me!";
// Create a new InlineUIContainer to contain the Button.
InlineUIContainer myInlineUIContainer = new InlineUIContainer();
// Set the BaselineAlignment property to "Bottom" so that the
// Button aligns properly with the text.
myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom;
// Asign the button as the UI container's child.
myInlineUIContainer.Child = myButton;
// Create the paragraph and add content to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(run1);
myParagraph.Inlines.Add(myInlineUIContainer);
myParagraph.Inlines.Add(run2);
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class InlineUIContainerExample
Inherits Page
Public Sub New()
Dim run1 As New Run(" Text to precede the button... ")
Dim run2 As New Run(" Text to follow the button... ")
' Create a new button to be hosted in the paragraph.
Dim myButton As New Button()
myButton.Content = "Click me!"
' Create a new InlineUIContainer to contain the Button.
Dim myInlineUIContainer As New InlineUIContainer()
' Set the BaselineAlignment property to "Bottom" so that the
' Button aligns properly with the text.
myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom
' Asign the button as the UI container's child.
myInlineUIContainer.Child = myButton
' Create the paragraph and add content to it.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(run1)
myParagraph.Inlines.Add(myInlineUIContainer)
myParagraph.Inlines.Add(run2)
' Create a FlowDocument and add the paragraph to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
Замечание
InlineUIContainer не требуется явно использовать в разметке. Если вы опустите его, InlineUIContainer все равно будет создано при компиляции кода.
Фигура и плавающий элемент
Figure и Floater используются для внедрения содержимого в поток документов с свойствами размещения, которые можно настроить независимо от основного потока контента. Figure или Floater элементы часто используются для выделения или акцентации частей содержимого, размещения вспомогательных изображений или другого содержимого в основном потоке контента или для внедрения свободно связанного содержимого, например рекламы.
В следующем примере показано, как внедрить Figure в абзац текста.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
<Figure
Width="300" Height="100"
Background="GhostWhite" HorizontalAnchor="PageLeft" >
<Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >
A Figure embeds content into flow content with placement properties
that can be customized independently from the primary content flow
</Paragraph>
</Figure>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi
enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class FigureExample : Page
{
public FigureExample()
{
// Create strings to use as content.
string strFigure = "A Figure embeds content into flow content with" +
" placement properties that can be customized" +
" independently from the primary content flow";
string strOther = "Lorem ipsum dolor sit amet, consectetuer adipiscing" +
" elit, sed diam nonummy nibh euismod tincidunt ut laoreet" +
" dolore magna aliquam erat volutpat. Ut wisi enim ad" +
" minim veniam, quis nostrud exerci tation ullamcorper" +
" suscipit lobortis nisl ut aliquip ex ea commodo consequat." +
" Duis autem vel eum iriure.";
// Create a Figure and assign content and layout properties to it.
Figure myFigure = new Figure();
myFigure.Width = new FigureLength(300);
myFigure.Height = new FigureLength(100);
myFigure.Background = Brushes.GhostWhite;
myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft;
Paragraph myFigureParagraph = new Paragraph(new Run(strFigure));
myFigureParagraph.FontStyle = FontStyles.Italic;
myFigureParagraph.Background = Brushes.Beige;
myFigureParagraph.Foreground = Brushes.DarkGreen;
myFigure.Blocks.Add(myFigureParagraph);
// Create the paragraph and add content to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(myFigure);
myParagraph.Inlines.Add(new Run(strOther));
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class FigureExample
Inherits Page
Public Sub New()
' Create strings to use as content.
Dim strFigure As String = "A Figure embeds content into flow content with" & " placement properties that can be customized" & " independently from the primary content flow"
Dim strOther As String = "Lorem ipsum dolor sit amet, consectetuer adipiscing" & " elit, sed diam nonummy nibh euismod tincidunt ut laoreet" & " dolore magna aliquam erat volutpat. Ut wisi enim ad" & " minim veniam, quis nostrud exerci tation ullamcorper" & " suscipit lobortis nisl ut aliquip ex ea commodo consequat." & " Duis autem vel eum iriure."
' Create a Figure and assign content and layout properties to it.
Dim myFigure As New Figure()
myFigure.Width = New FigureLength(300)
myFigure.Height = New FigureLength(100)
myFigure.Background = Brushes.GhostWhite
myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft
Dim myFigureParagraph As New Paragraph(New Run(strFigure))
myFigureParagraph.FontStyle = FontStyles.Italic
myFigureParagraph.Background = Brushes.Beige
myFigureParagraph.Foreground = Brushes.DarkGreen
myFigure.Blocks.Add(myFigureParagraph)
' Create the paragraph and add content to it.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(myFigure)
myParagraph.Inlines.Add(New Run(strOther))
' Create a FlowDocument and add the paragraph to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
На следующем рисунке показано, как отрисовывается этот пример.
Figure и Floater отличаются несколькими способами и используются для разных сценариев.
Цифра:
Можно разместить: можно задать горизонтальные и вертикальные привязки, чтобы закрепить его относительно страницы, содержимого, столбца или абзаца. Вы также можете использовать его HorizontalOffset и VerticalOffset свойства для указания произвольного смещения.
Можно изменить размер на несколько столбцов: вы можете установить высоту и ширину Figure кратными высоте или ширине страницы, содержимого или столбцов. Обратите внимание, что в случае страницы и содержимого множители, превышающие 1, не допускаются. Например, можно задать ширину Figure страницы "0,5" или "0,25 содержимого" или "2 столбца". Вы также можете задать высоту и ширину абсолютным значениям пикселей.
Не пагинирует: если содержимое внутри Figure не помещается внутри Figure, будет показано только то содержимое, которое помещается, а оставшееся содержимое будет потеряно.
Поплавок:
Невозможно задать фиксированное положение, и элемент будет выводиться там, где для него найдется место. Невозможно задать смещение или установить якорь для Floater.
Нельзя задать размер более чем для одного столбца: по умолчанию Floater имеет размер одного столбца. Он имеет Width свойство, которое может быть задано абсолютным значением пикселя, но если это значение больше одной ширины столбца, оно игнорируется, а плавающая строка имеет размер по одному столбцу. Вы можете уменьшить размер до менее чем одного столбца, задав правильную ширину в пикселях, но размер не зависит от ширины столбца, поэтому "0.5Column" не является допустимым выражением для ширины Floater. Floater не имеет свойства высоты и не может быть задана высота, она зависит от содержимого.
Floater пагинация: если его содержимое по заданной ширине превышает высоту одного столбца, плавающие блоки разбиваются и переносятся на следующий столбец, следующую страницу и т. д.
Figure — это хорошее место для размещения автономного содержимого, в котором вы хотите контролировать размер и расположение, и уверены, что содержимое будет соответствовать указанному размеру. Floater является хорошим местом для размещения более свободного содержимого, которое структурировано аналогично основному содержимому, но отделено от него.
LineBreak
LineBreak Вызывает разрыв строки в содержимом потока. В следующем примере показано использование LineBreak.
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Before the LineBreak in Paragraph.
<LineBreak />
After the LineBreak in Paragraph.
<LineBreak/><LineBreak/>
After two LineBreaks in Paragraph.
</Paragraph>
<Paragraph>
<LineBreak/>
</Paragraph>
<Paragraph>
After a Paragraph with only a LineBreak in it.
</Paragraph>
</FlowDocument>
На следующем снимке экрана показано, как отображается этот пример.
Элементы коллекции потоков
Во многих приведённых выше примерах BlockCollection и InlineCollection используются для программного создания содержимого потока. Например, чтобы добавить элементы в объект Paragraph, можно использовать синтаксис:
myParagraph.Inlines.Add(new Run("Some text"));
Это добавляет Run к InlineCollection в Paragraph. Это то же самое, что и неявное Run , найденное внутри Paragraph разметки:
<Paragraph>
Some Text
</Paragraph>
В качестве примера использования BlockCollectionв следующем примере создается новое Section , а затем используется метод Add для добавления нового Paragraph в содержимое Section .
Section secx = new Section();
secx.Blocks.Add(new Paragraph(new Run("A bit of text content...")));
Dim secx As New Section()
secx.Blocks.Add(New Paragraph(New Run("A bit of text content...")))
Помимо добавления элементов в коллекцию потоков, можно также удалить элементы. В следующем примере удаляется последний элемент Inline в Span.
spanx.Inlines.Remove(spanx.Inlines.LastInline);
spanx.Inlines.Remove(spanx.Inlines.LastInline)
В следующем примере из Inlineудаляется все содержимое (элементыSpan).
spanx.Inlines.Clear();
spanx.Inlines.Clear()
При программировании с потоковым содержимым вы, вероятно, будете активно использовать эти коллекции.
Зависит от того, какие дочерние элементы (InlineCollection или BlockCollection) могут содержаться родительским элементом: использует ли элемент потока Block (Inlines) или Inline (Blocks) для своих дочерних элементов. Правила содержания для элементов содержимого потока приведены в схеме содержимого в следующем разделе.
Замечание
Существует третий тип коллекции, который используется с поточным содержимым, ListItemCollection, но эта коллекция используется только с List. Кроме того, существует несколько коллекций, используемых с Table. Дополнительные сведения см. в разделе "Общие сведения о таблице".
Схема содержимого
Учитывая количество различных элементов содержимого потока, бывает непросто следить за тем, какие типы дочерних элементов может содержать элемент. На приведенной ниже схеме приведены правила хранения для элементов потока. Стрелки представляют возможные взаимоотношения между родительскими и дочерними элементами.
диаграмма
Как видно на схеме выше, дочерние элементы, разрешенные для элемента, не обязательно определяются тем, является ли он элементом Block или элементом Inline . Например, Span (элемент Inline ) может содержать только дочерние элементы типа Inline, а Figure (также элемент Inline) может содержать только дочерние элементы типа Block. Таким образом, схема полезна для быстрого определения элемента, который может содержаться в другом. В качестве примера рассмотрим схему, чтобы определить, как создать содержимое потока RichTextBox.
1. Должен RichTextBox содержать объект FlowDocument , который, в свою очередь, должен содержать производный Blockобъект. Ниже приведен соответствующий сегмент из приведенной выше схемы.
схема
Вот как может выглядеть разметка на данный момент.
<RichTextBox>
<FlowDocument>
<!-- One or more Block-derived object… -->
</FlowDocument>
</RichTextBox>
2. В соответствии с схемой существует несколько Block элементов, которые следует выбрать, в том числеParagraph, SectionTable, Listи BlockUIContainer (см. производные от блока классы выше). Предположим, что мы хотим Table. Согласно приведенной выше схеме, объект Table содержит TableRowGroup, которые содержат элементы TableRow, которые содержат элементы TableCell, содержащие производный объект Block. Ниже приведен соответствующий сегмент из схемы, приведенной выше, Table.
схема
Ниже приведена соответствующая разметка.
<RichTextBox>
<FlowDocument>
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<!-- One or more Block-derived object… -->
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</RichTextBox>
3. Снова требуется один или несколько Block элементов под TableCell. Чтобы сделать его простым, давайте поместим текст внутри ячейки. Это можно сделать с помощью Paragraph с элементом Run. Ниже приведены соответствующие сегменты на схеме, показывающие, что Paragraph может принимать Inline элемент, а что Run (элемент Inline) может принимать только обычный текст.
Диаграмма
схема
Внизу представлен полный пример разметки.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<RichTextBox>
<FlowDocument>
<!-- Normally a table would have multiple rows and multiple
cells but this code is for demonstration purposes.-->
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<Paragraph>
<!-- The schema does not actually require
explicit use of the Run tag in markup. It
is only included here for clarity. -->
<Run>Paragraph in a Table Cell.</Run>
</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</RichTextBox>
</Page>
Настройка текста
Обычно текст является наиболее распространенным типом содержимого в документе потока. Хотя приведенные выше объекты можно использовать для управления большинством аспектов отрисовки текста, существуют некоторые другие методы настройки текста, описанные в этом разделе.
Украшения текста
Украшения текста позволяют применять подчеркивание, перестроку, базовые и зачеркнутые эффекты к тексту (см. рисунки ниже). Эти украшения добавляются с помощью свойства TextDecorations, которое предоставляется рядом объектов, включая Inline, Paragraph, TextBlock и TextBox.
В следующем примере показано, как задать TextDecorations свойство объекта Paragraph.
<FlowDocument ColumnWidth="200">
<Paragraph TextDecorations="Strikethrough">
This text will render with the strikethrough effect.
</Paragraph>
</FlowDocument>
Paragraph parx = new Paragraph(new Run("This text will render with the strikethrough effect."));
parx.TextDecorations = TextDecorations.Strikethrough;
Dim parx As New Paragraph(New Run("This text will render with the strikethrough effect."))
parx.TextDecorations = TextDecorations.Strikethrough
На следующем рисунке показано, как отрисовывается этот пример.
На следующих рисунках показано, как отображаются декорации Overline, Базовая линия и Подчеркивание соответственно.
Типографика
Свойство Typography доступно в большинстве связанного с потоком содержимого, включая TextElement, FlowDocument, TextBlock и TextBox. Это свойство используется для управления типографическими характеристиками и вариациями текста (т. е. малых или больших прописных букв, создания верхних и нижних индексов и т. д.).
В следующем примере показано, как задать атрибут Typography, используя Paragraph в качестве примера элемента.
<Paragraph
TextAlignment="Left"
FontSize="18"
FontFamily="Palatino Linotype"
Typography.NumeralStyle="OldStyle"
Typography.Fraction="Stacked"
Typography.Variants="Inferior"
>
<Run>
This text has some altered typography characteristics. Note
that use of an open type font is necessary for most typographic
properties to be effective.
</Run>
<LineBreak/><LineBreak/>
<Run>
0123456789 10 11 12 13
</Run>
<LineBreak/><LineBreak/>
<Run>
1/2 2/3 3/4
</Run>
</Paragraph>
На следующем рисунке показано, как отрисовывается этот пример.
Напротив, на следующем рисунке показано, как аналогичный пример с типографическими свойствами по умолчанию отображается.
В следующем примере показано, как программно задать свойство Typography.
Paragraph par = new Paragraph();
Run runText = new Run(
"This text has some altered typography characteristics. Note" +
"that use of an open type font is necessary for most typographic" +
"properties to be effective.");
Run runNumerals = new Run("0123456789 10 11 12 13");
Run runFractions = new Run("1/2 2/3 3/4");
par.Inlines.Add(runText);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runNumerals);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runFractions);
par.TextAlignment = TextAlignment.Left;
par.FontSize = 18;
par.FontFamily = new FontFamily("Palatino Linotype");
par.Typography.NumeralStyle = FontNumeralStyle.OldStyle;
par.Typography.Fraction = FontFraction.Stacked;
par.Typography.Variants = FontVariants.Inferior;
Dim par As New Paragraph()
Dim runText As New Run("This text has some altered typography characteristics. Note" & "that use of an open type font is necessary for most typographic" & "properties to be effective.")
Dim runNumerals As New Run("0123456789 10 11 12 13")
Dim runFractions As New Run("1/2 2/3 3/4")
par.Inlines.Add(runText)
par.Inlines.Add(New LineBreak())
par.Inlines.Add(New LineBreak())
par.Inlines.Add(runNumerals)
par.Inlines.Add(New LineBreak())
par.Inlines.Add(New LineBreak())
par.Inlines.Add(runFractions)
par.TextAlignment = TextAlignment.Left
par.FontSize = 18
par.FontFamily = New FontFamily("Palatino Linotype")
par.Typography.NumeralStyle = FontNumeralStyle.OldStyle
par.Typography.Fraction = FontFraction.Stacked
par.Typography.Variants = FontVariants.Inferior
См. типографику в WPF для получения дополнительной информации о типографии.
См. также
.NET Desktop feedback