TOC

This article is currently in the process of being translated into Russian (~46% 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, полосы прокрутки будут невидимы до тех пор, пока содержимое фактически не выйдет за пределы доступного пространства (обычно это то, что вам нужно).

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

You may have noticed that I specifically used the TextAlignment property in the above examples. That's because the text is rendered justified by default, in a WPF FlowDocument, meaning that each line of text is stretched to cover the entire available width, if needed. As you can see, this can be changed, either on a single paragraph or globally for the entire document by setting the same property on the FlowDocument element.

However, in many situations, justified text makes sense, but it can result in some very bad layout, with very excessive amounts of whitespace on lines where a linebreak is inserted right before a very long word.

The following example will illustrate that, as well as provide a solution that will help remedy the problem. By using the IsOptimalParagraphEnabled property in combination with the IsHyphenationEnabled property, you will give WPF a better chance of laying out the text in the best possible way.

IsOptimalParagraphEnabled allows WPF to look ahead in your text, to see if it would make more sense to break the text in a different position than right at the moment where it runs out of space. IsHyphenationEnabled allows WPF to split your words with a hyphen, if it would allow for a more natural layout of the text.

In the next example, I've rendered the same text twice - one without these properties, and one with. The difference is quite obvious:

<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 is not enabled by default because it does require a bit more CPU power when rendering the text, especially if the window is frequently resized. For most situations this shouldn't be a problem though.

If you have a lot of FlowDocument instances in your application and you prefer this optimal rendering method, you can enable it on all of your FlowDocument instances by specifying a global style that enables it, in your App.xaml. Here's an example:

<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!