Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Program Windows Presentation Foundation (WPF) udostępnia niezawodny zestaw interfejsów API do dołączania tekstu do aplikacji. API interfejsu użytkownika (UI), takie jak TextBlock, udostępniają najbardziej typowe i uniwersalne elementy do prezentacji tekstu. Interfejsy API rysunku, takie jak GlyphRunDrawing i FormattedText, zapewniają metodę dołączania tekstu sformatowanego w rysunkach. Na najbardziej zaawansowanym poziomie WPF zapewnia rozszerzalny aparat formatowania tekstu do kontrolowania każdego aspektu prezentacji tekstu, takich jak zarządzanie magazynem tekstu, zarządzanie formatowaniem przebiegu tekstu i zarządzanie osadzonymi obiektami.
Ten temat zawiera wprowadzenie do formatowania tekstu WPF. Koncentruje się na implementacji klienta i użyciu silnika formatowania tekstu WPF.
Uwaga / Notatka
Wszystkie przykłady kodu w tym dokumencie można znaleźć w przykładzie Zaawansowane formatowanie tekstu.
Wymagania wstępne
W tym temacie założono, że znasz interfejsy API wyższego poziomu używane do prezentacji tekstu. Większość scenariuszy użytkownika nie wymaga zaawansowanych interfejsów API formatowania tekstu omówionych w tym temacie. Aby zapoznać się z wprowadzeniem do różnych interfejsów API tekstu, zobacz Dokumenty w WPF.
Zaawansowane formatowanie tekstu
Układ tekstu i kontrolki interfejsu użytkownika w WPF zapewniają właściwości formatowania, które umożliwiają łatwe dołączanie sformatowanego tekstu w aplikacji. Sterowniki te udostępniają szereg właściwości do obsługi prezentacji tekstu, w tym krój pisma, rozmiar i kolor. W zwykłych okolicznościach te kontrolki mogą obsługiwać większość prezentacji tekstu w aplikacji. Jednak niektóre zaawansowane scenariusze wymagają kontroli magazynu tekstu, a także prezentacji tekstu. WPF zapewnia rozszerzalny aparat formatowania tekstu w tym celu.
Zaawansowane funkcje formatowania tekstu dostępne w WPF składają się z silnika formatowania tekstu, magazynu tekstu, sekwencji tekstu i właściwości formatowania. Mechanizm formatowania tekstu TextFormatter tworzy wiersze tekstu, które mają być używane do prezentacji. Jest to osiągane przez zainicjowanie procesu formatowania wiersza i wywołanie elementu formatującego tekst .FormatLine Program formatujący tekst pobiera ciągi tekstowe z magazynu tekstu, poprzez wywołanie metody magazynu GetTextRun. Obiekty TextRun są następnie tworzone w TextLine obiekty przez program formatujący tekst i przekazywane aplikacji do inspekcji lub wyświetlania.
Korzystanie z programu formatującego tekst
TextFormatter to aparat formatowania tekstu WPF i zapewnia usługi formatowania i przerywania wierszy tekstu. Program formatujący tekst może obsługiwać różne formaty znaków tekstowych i style akapitu oraz obsługuje międzynarodowy układ tekstu.
W przeciwieństwie do tradycyjnego interfejsu API tekstu TextFormatter współdziała z klientem układu tekstu za pomocą zestawu metod wywołania zwrotnego. Wymaga to, aby klient dostarczył te metody we wdrożeniu klasy TextSource. Na poniższym diagramie przedstawiono interakcję układu tekstu między aplikacją kliencą a TextFormatter.
Program formatujący tekst służy do pobierania sformatowanych wierszy tekstu z magazynu tekstu, który jest implementacją elementu TextSource. Najpierw wykonuje się to przez utworzenie wystąpienia formatera tekstu przy użyciu metody Create. Ta metoda tworzy instancję formatera tekstu i ustawia maksymalną wysokość i szerokość linii. Po utworzeniu wystąpienia formatującego tekstu, proces tworzenia wiersza jest uruchamiany poprzez wywołanie metody FormatLine. TextFormatter odwołuje się do źródła tekstu, aby pobrać tekst i parametry formatowania dla fragmentów tekstu, które tworzą wiersz.
W poniższym przykładzie pokazano proces formatowania magazynu tekstu. Obiekt TextFormatter jest używany do pobierania wierszy tekstu z magazynu tekstu, a następnie formatowania wiersza tekstu do renderowania w obiekcie DrawingContext.
// Create a DrawingGroup object for storing formatted text.
textDest = new DrawingGroup();
DrawingContext dc = textDest.Open();
// Update the text store.
_textStore.Text = textToFormat.Text;
_textStore.FontRendering = _currentRendering;
// Create a TextFormatter object.
TextFormatter formatter = TextFormatter.Create();
// Format each line of text from the text store and draw it.
while (textStorePosition < _textStore.Text.Length)
{
// Create a textline from the text store using the TextFormatter object.
using (TextLine myTextLine = formatter.FormatLine(
_textStore,
textStorePosition,
96*6,
new GenericTextParagraphProperties(_currentRendering),
null))
{
// Draw the formatted text into the drawing context.
myTextLine.Draw(dc, linePosition, InvertAxes.None);
// Update the index position in the text store.
textStorePosition += myTextLine.Length;
// Update the line position coordinate for the displayed line.
linePosition.Y += myTextLine.Height;
}
}
// Persist the drawn text content.
dc.Close();
// Display the formatted text in the DrawingGroup object.
myDrawingBrush.Drawing = textDest;
' Create a DrawingGroup object for storing formatted text.
textDest = New DrawingGroup()
Dim dc As DrawingContext = textDest.Open()
' Update the text store.
_textStore.Text = textToFormat.Text
_textStore.FontRendering = _currentRendering
' Create a TextFormatter object.
Dim formatter As TextFormatter = TextFormatter.Create()
' Format each line of text from the text store and draw it.
Do While textStorePosition < _textStore.Text.Length
' Create a textline from the text store using the TextFormatter object.
Using myTextLine As TextLine = formatter.FormatLine(_textStore, textStorePosition, 96*6, New GenericTextParagraphProperties(_currentRendering), Nothing)
' Draw the formatted text into the drawing context.
myTextLine.Draw(dc, linePosition, InvertAxes.None)
' Update the index position in the text store.
textStorePosition += myTextLine.Length
' Update the line position coordinate for the displayed line.
linePosition.Y += myTextLine.Height
End Using
Loop
' Persist the drawn text content.
dc.Close()
' Display the formatted text in the DrawingGroup object.
myDrawingBrush.Drawing = textDest
Implementowanie repozytorium tekstu klienta
Po rozszerzeniu aparatu formatowania tekstu wymagane jest zaimplementowanie wszystkich aspektów magazynu tekstu i zarządzanie nimi. Nie jest to proste zadanie. Magazyn tekstu jest odpowiedzialny za śledzenie właściwości przebiegu tekstu, właściwości akapitu, obiektów osadzonych i inną podobną zawartość. Udostępnia również program formatujący tekst z poszczególnymi TextRun obiektami, których program formatujący tekst używa do tworzenia TextLine obiektów.
Aby obsłużyć wirtualizację magazynu tekstu, magazyn tekstu musi pochodzić z TextSource. TextSource definiuje metodę używaną przez program formatujący tekst do pobierania przebiegów tekstu z magazynu tekstu. GetTextRun to metoda używana przez program formatujący tekst do pobierania przebiegów tekstu używanych w formatowaniu wiersza. Wywołanie GetTextRun jest wielokrotnie wykonywane przez program formatujący tekst aż do momentu wystąpienia jednego z następujących warunków:
Zwracana jest TextEndOfLine lub podklasa.
Łączna szerokość sekcji tekstu przekracza maksymalną dopuszczalną szerokość linii określoną przy tworzeniu formatera tekstu lub wywołaniu jego metody FormatLine.
Zwracana jest sekwencja nowego wiersza Unicode, technicznie określana jako "CF", "LF" lub "CRLF".
Dostarczanie segmentów tekstu
Rdzeniem procesu formatowania tekstu jest interakcja między formatatorem tekstu a magazynem tekstu. Implementacja TextSource dostarcza formatującemu tekst TextRun obiekty i właściwości, za pomocą których formatuje przebiegi tekstu. Ta interakcja jest obsługiwana przez metodę GetTextRun , która jest wywoływana przez program formatujący tekst.
W poniższej tabeli przedstawiono niektóre wstępnie zdefiniowane TextRun obiekty.
| Typ tekstu | Zastosowanie |
|---|---|
| TextCharacters | Specjalistyczna sekwencja tekstowa służąca do przesyłania reprezentacji glifów znaków do formatującego tekst. |
| TextEmbeddedObject | Wyspecjalizowany przebieg tekstu używany do udostępniania zawartości, w której odbywa się pomiar, testowanie trafień i rysowanie, takie jak przycisk lub obraz w tekście. |
| TextEndOfLine | Wyspecjalizowany przebieg tekstu używany do oznaczania końca wiersza. |
| TextEndOfParagraph | Wyspecjalizowany przebieg tekstu używany do oznaczania końca akapitu. |
| TextEndOfSegment | Wyspecjalizowany fragment tekstu używany do oznaczania końca segmentu, na przykład w celu zakończenia zakresu objętego przez poprzedni przebieg TextModifier. |
| TextHidden | Wyspecjalizowany fragment tekstu używany do oznaczania zakresu ukrytych znaków. |
| TextModifier | Wyspecjalizowany fragment tekstu używany do modyfikowania właściwości fragmentów tekstu znajdujących się w jego zakresie. Zakres obejmuje następny pasujący fragment tekstu TextEndOfSegment lub następny TextEndOfParagraph. |
Każdy ze wstępnie zdefiniowanych TextRun obiektów może być podklasowany. To umożliwia Twojemu źródłu tekstu dostarczenie formaterowi tekstu segmentów tekstowych zawierających dane niestandardowe.
W poniższym przykładzie przedstawiono metodę GetTextRun . Ten magazyn tekstu zwraca TextRun obiekty do formatowania tekstu do przetwarzania.
// Used by the TextFormatter object to retrieve a run of text from the text source.
public override TextRun GetTextRun(int textSourceCharacterIndex)
{
// Make sure text source index is in bounds.
if (textSourceCharacterIndex < 0)
throw new ArgumentOutOfRangeException("textSourceCharacterIndex", "Value must be greater than 0.");
if (textSourceCharacterIndex >= _text.Length)
{
return new TextEndOfParagraph(1);
}
// Create TextCharacters using the current font rendering properties.
if (textSourceCharacterIndex < _text.Length)
{
return new TextCharacters(
_text,
textSourceCharacterIndex,
_text.Length - textSourceCharacterIndex,
new GenericTextRunProperties(_currentRendering));
}
// Return an end-of-paragraph if no more text source.
return new TextEndOfParagraph(1);
}
' Used by the TextFormatter object to retrieve a run of text from the text source.
Public Overrides Function GetTextRun(ByVal textSourceCharacterIndex As Integer) As TextRun
' Make sure text source index is in bounds.
If textSourceCharacterIndex < 0 Then
Throw New ArgumentOutOfRangeException("textSourceCharacterIndex", "Value must be greater than 0.")
End If
If textSourceCharacterIndex >= _text.Length Then
Return New TextEndOfParagraph(1)
End If
' Create TextCharacters using the current font rendering properties.
If textSourceCharacterIndex < _text.Length Then
Return New TextCharacters(_text, textSourceCharacterIndex, _text.Length - textSourceCharacterIndex, New GenericTextRunProperties(_currentRendering))
End If
' Return an end-of-paragraph if no more text source.
Return New TextEndOfParagraph(1)
End Function
Uwaga / Notatka
W tym przykładzie magazyn tekstu udostępnia te same właściwości tekstu wszystkim tekstom. Zaawansowane magazyny tekstu muszą zaimplementować własne zarządzanie zakresem, aby umożliwić poszczególnym znakom różne właściwości.
Określanie właściwości formatowania
TextRun obiekty są formatowane przy użyciu właściwości udostępnianych przez magazyn tekstów. Te właściwości są dostępne w dwóch typach: TextParagraphProperties i TextRunProperties. TextParagraphProperties obsługa właściwości inkluzywnych akapitów, takich jak TextAlignment i FlowDirection. TextRunProperties to właściwości, które mogą być różne dla każdego przebiegu tekstu w akapicie, takie jak pędzel koloru pierwszego planu, Typeface oraz rozmiar czcionki. Aby zaimplementować niestandardowe typy właściwości akapitu i niestandardowego przebiegu tekstu, aplikacja musi utworzyć klasy, które pochodzą odpowiednio z TextParagraphProperties i TextRunProperties .
Zobacz także
.NET Desktop feedback