TOC

This article is currently in the process of being translated into Russian (~98% done).

Элементы управления текстом:

The FlowDocumentScrollViewer control

Из всех оберток FlowDocument, которые обсуждались во введении, FlowDocumentScrollViewer является наиболее простым. Он позволяет пользователям листать длинные документы, используя обычные полосы прокрутки. Поскольку это наша первая встреча с FlowDocument, используемого в любой форме, мы начнем с простого примера 'Hello World!', и помимо использования FlowDocumentScrollViewer, в этой статья будут также обсуждаться несколько концепций, общих для всех оберток.

<Window x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentScrollViewerSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FlowDocumentScrollViewerSample" Height="200" Width="300">
    <Grid>
        <FlowDocumentScrollViewer>
            <FlowDocument>
                <Paragraph FontSize="36">Hello, world!</Paragraph>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">The ultimate programming greeting!</Paragraph>
            </FlowDocument>
        </FlowDocumentScrollViewer>
    </Grid>
</Window>

Обратите внимание, как легко было указать текст, используя простые теги разметки, в данном случае тег Paragraph. Теперь вы можете утверждать, что этого можно было достичь с помощью пары элементов управления TextBlock, и вы были бы абсолютно правы, но даже с таким базовым примером, как этот, вы получаете немного дополнительной функциональности бесплатно: вы можете выделить текст и скопировать его в буфер обмена. Это будет выглядеть так:

Масштабирование и видимость полосы прокрутки

Как упоминалось ранее, все обертки FlowDocument поддерживают масштабирование из коробки. В приведенном выше примере вы можете просто удерживать клавишу Ctrl, используя колесико мыши для увеличения или уменьшения масштаба. Это может быть не очевидно для ваших конечных пользователей, поэтому вы можете помочь им, отобразив встроенную панель инструментов FlowDocumentScrollViewer, в которой есть элементы управления, которые позволят вам изменить уровень масштабирования. Просто установите для свойства IsToolBarVisible значение true в FlowDocumentScrollViewer, и все готово, как вы можете видеть в следующем примере:

<Window x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentScrollViewerZoomSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FlowDocumentScrollViewerZoomSample" Height="180" Width="300">
    <Grid>
        <FlowDocumentScrollViewer IsToolBarVisible="True" Zoom="80" ScrollViewer.VerticalScrollBarVisibility="Auto">
            <FlowDocument>
                <Paragraph FontSize="36">Hello, world!</Paragraph>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">The ultimate programming greeting!</Paragraph>
            </FlowDocument>
        </FlowDocumentScrollViewer>
    </Grid>
</Window>

Теперь пользователь может управлять уровнем масштабирования с помощью ползунка и кнопок на панели инструментов под документом. Также обратите внимание, что мы изменили уровень масштабирования по умолчанию, используя свойство Zoom - оно определяет уровень масштабирования в процентах, так что в нашем случае текст по умолчанию уменьшится до 80%.

Последнее, что я изменил в этом примере, по сравнению с первым, это использование свойства ScrollViewer.VerticalScrollBarVisibility. Если установить значение в Auto, полосы прокрутки будут невидимы до тех пор, пока содержимое фактически не выйдет за пределы доступного пространства (обычно это то, что вам нужно).

Выравнивание текста

Вы могли заметить, что я целенаправленно использовал свойство TextAlignment в предыдущих примерах. Это связано с тем, что текст в компоненте WPF FlowDocument по-умолчанию выровнен по ширине. Каждая строка текста при необходимости растягивается, занимая все доступное пространство. Как вы видите, это можно изменить как для каждого параграфа по отдельности, так и глобально для всего документа установкой аналогичного свойства для элемента FlowDocument.

Однако во многих случаях использование выровненного по ширине текста имеет смысл, однако может привести к нежелательным результатам в виде избыточного количества пробелов в строке, где признак конца строки вставлен перед очень длинным словом.

Следующий пример проиллюстрирует это, а также покажет решение, которое поможет устранить проблему. Используя свойство IsOptimalParagraphEnabled в сочетании со свойством IsHyphenationEnabled вы дадите WPF больше возможностей расположить текст наилучшим из возможных способом.

Свойство IsOptimalParagraphEnabled позволяет WPF анализировать текст наперед, определяя оптимальное место разрыва строки. Свойство IsHyphenationEnabled разрешает WPF разбивать слова знаками переноса, если это позволит разместить текст более естественным образом.

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

<Window x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentTextAlignmentSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="FlowDocumentTextAlignmentSample" Height="400" Width="330">
    <StackPanel>
        <FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
            <FlowDocument>
                <Paragraph FontStyle="Italic" FontSize="14" Foreground="Gray">
                    By setting the
                    <Bold>IsOptimalParagraphEnabled</Bold> property to true,
                    you will allow WPF to look ahead on the lines to come, before deciding
                    where to break. This will usually result in a more pleasant reading
                    experience. It works especially well in combination with the
                    <Bold>IsHyphenationEnabled</Bold> property.
                </Paragraph>
            </FlowDocument>
        </FlowDocumentScrollViewer>
        <FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
            <FlowDocument IsOptimalParagraphEnabled="True" IsHyphenationEnabled="True">
                <Paragraph FontStyle="Italic" FontSize="14" Foreground="Gray">
                    By setting the <Bold>IsOptimalParagraphEnabled</Bold> property to true,
                    you will allow WPF to look ahead on the lines to come, before deciding
                    where to break. This will usually result in a more pleasant reading
                    experience. It works especially well in combination with the
                    <Bold>IsHyphenationEnabled</Bold> property.
                </Paragraph>
            </FlowDocument>
        </FlowDocumentScrollViewer>
    </StackPanel>
</Window>

Свойство IsOptimalParagraphEnabled не установлено по-умолчанию, поскольку требует немного больше ресурсов CPU для отображения текста, особенно если окно часто изменяется в размерах. Однако в большинстве ситуаций это не станет проблемой.

Если ваше приложение содержит множество экземпляров FlowDocument и вы предпочитаете оптимальный метод отображения, вы можете разрешить использование этого свойства для всех экземпляров FlowDocument, назначив соответствующий глобальный стиль в App.xaml:

<Application x:Class="WpfTutorialSamples.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             StartupUri="Rich text controls/FlowDocumentTextAlignmentSample.xaml">
    <Application.Resources>
        <Style TargetType="FlowDocument">
            <Setter Property="IsOptimalParagraphEnabled" Value="True" />
            <Setter Property="IsHyphenationEnabled" Value="True" />
        </Style>
    </Application.Resources>
</Application>
This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!