TOC

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

Kontrolki Rich Text:

The FlowDocumentScrollViewer control

W gamie wrapperów FlowDocument, omówionych we wstępie, najprostszym jest FlowDocumentScrollViewer. Pozwala on użytkownikom na przewijanie długich dokumentów, używając zwykłych pasków przewijania. Ponieważ jest to nasze pierwsze spotkanie z FlowDocument użytym w jakiejkolwiek formie, zaczniemy od podstawowego przykładu "Hello World", a oprócz użycia FlowDocumentScrollViewer, w tym artykule omówimy również kilka koncepcji wspólnych dla wszystkich wrapperów. Oto pierwszy przykład:

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

Zauważ jak prosto było określić tekst, używając prostych znaczników, w tym przypadku znacznik Paragraph. Teraz możesz się spierać, że można to było osiągnąć za pomocą kilku kontrolek TextBlock, i miałbyś całkowitą rację, ale nawet w tak podstawowym przykładzie, jak ten, dostajesz trochę dodatkowej funkcjonalności za darmo: Możesz zaznaczyć tekst i skopiować go do schowka. Będzie to wyglądało tak:

Powiększanie i widoczność paska przewijania

Jak już wcześniej wspomniano, wszystkie wrappery FlowDocument obsługują powiększanie zaraz na starcie. W powyższym przykładzie można po prostu przytrzymać klawisz Ctrl i używając kółka myszy, przybliżać i oddalać. Może to jednak nie być oczywiste dla użytkowników końcowych, dlatego można im pomóc, wyświetlając wbudowany pasek narzędzi FlowDocumentScrollViewer, który zawiera kontrolki umożliwiające zmianę poziomu powiększenia. Wystarczy ustawić właściwość IsToolBarVisible na "true" w FlowDocumentScrollViewer i to wszystko, tak jak widać to na kolejnym przykładzie:

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

Teraz użytkownik może kontrolować poziom powiększenia za pomocą suwaka i przycisków na pasku narzędzi pod dokumentem. Zauważ również, że zmieniliśmy domyślny poziom powiększenia, używając właściwości Zoom - definiuje ona poziom powiększenia w procentach, więc w tym przypadku tekst jest domyślnie oddalony do 80%.

Ostatnią rzeczą, którą zmieniłem w tym przykładzie, w porównaniu do pierwszego, jest użycie właściwości ScrollViewer.VerticalScrollBarVisibility. Ustawiając ją na Auto, paski przewijania będą niewidoczne, dopóki zawartość nie wykroczy poza dostępną przestrzeń, co zazwyczaj jest tym, czego oczekujesz.

Wyrównanie tekstu

Być może zauważyłeś, że w powyższych przykładach specjalnie użyłem właściwości TextAlignment. Dzieje się tak dlatego, że tekst jest domyślnie renderowany jako justowany w WPF FlowDocument, co oznacza, że każda linia tekstu jest rozciągnięta na całą dostępną szerokość, jeżeli jest to konieczne. Jak widać, można to zmienić, zarówno w pojedynczym akapicie, jak i globalnie dla całego dokumentu, ustawiając tę samą właściwość w elemencie FlowDocument.

Jednak w wielu sytuacjach justowanie tekstu ma sens, ale może skutkować bardzo złym układem strony, z nadmierną ilością białych przestrzeni w liniach, w których znak nowej linii jest wstawiany tuż przed bardzo długim słowem.

Poniższy przykład zilustruje to, jak również dostarczy rozwiązania, które pomoże rozwiązać ten problem. Poprzez użycie właściwości IsOptimalParagraphEnabled w połączeniu z właściwością IsHyphenationEnabled, dasz WPF większe szanse na ułożenie tekstu w najlepszy możliwy sposób.

IsOptimalParagraphEnabled pozwala WPF spojrzeć na twój tekst, aby sprawdzić, czy bardziej sensowne byłoby złamanie tekstu w innym miejscu niż w momencie, gdy zabraknie miejsca. IsHyphenationEnabled pozwala WPF na dzielenie słów myślnikiem, jeśli pozwoliłoby to na bardziej naturalny układ tekstu.

W następnym przykładzie, wyrenderowałem ten sam tekst dwa razy - raz bez tych właściwości, a raz z nimi. Różnica jest dość oczywista:

<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 nie jest domyślnie włączone, ponieważ wymaga nieco więcej mocy procesora podczas renderowania tekstu, szczególnie jeśli okno jest często zmieniane. W większości sytuacji nie powinno to jednak stanowić problemu.

Jeśli masz wiele instancji FlowDocument w swojej aplikacji i preferujesz tę optymalną metodę renderowania, możesz ją włączyć we wszystkich instancjach FlowDocument, określając styl globalny, który ją włącza, w pliku App.xaml. Oto przykład:

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