Optimieren der Leistung: Text
WPF bietet Unterstützung für die Präsentation des Textinhalts durch die Verwendung umfangreicher user interface (UI)-Steuerelemente. Im Allgemeinen können Sie das Rendern von Text in drei Ebenen unterteilen:
Direktes Verwenden des Glyphs-Objekts und des GlyphRun-Objekts.
Verwenden des FormattedText-Objekts.
Verwenden von übergeordneten Steuerelementen, z. B. des TextBlock-Objekts und des FlowDocument-Objekts.
Dieses Thema enthält Empfehlungen in Bezug auf die Leistung beim Rendern von Text.
Dieses Thema enthält folgende Abschnitte.
- Rendern von Text auf der Symbolebene
- FormattedText-Objekt
- FlowDocument-, TextBlock- und Label-Steuerelement
- Link
- Textformatierungsfeatures
- Verwandte Abschnitte
Rendern von Text auf der Symbolebene
Windows Presentation Foundation (WPF) bietet für Kunden, die den formatierten Text abfangen und beibehalten möchten, eine erweiterte Textunterstützung (einschließlich Markup auf Symbolebene) mit einem direkten Zugriff auf Glyphs. Diese Features unterstützen die verschiedenen Anforderungen, die sich aus jedem der folgenden Szenarien an das Rendern von Text ergeben.
Bildschirmanzeige von Dokumenten mit festem Format.
Druckszenarien.
Extensible Application Markup Language (XAML) als Gerätesprache für den Drucker.
Microsoft XPS Document Writer.
Vorherige Druckertreiber, Ausgabe von Win32-Anwendungen in das feste Format.
Druckerspoolformat.
Dokumentendarstellung im festen Format einschließlich Clients für vorherige Versionen von Windows und anderer Computer.
Hinweis |
---|
Glyphs und GlyphRun sind für die Dokumentendarstellung und für Druckszenarien im festen Format ausgelegt.Windows Presentation Foundation (WPF) stellt etliche Elemente für allgemeine Layout- und user interface (UI)-Szenarien, z. B. Label und TextBlock, zur Verfügung.Weitere Informationen über Layout- und UI-Szenarien finden Sie unter Typografie in WPF. |
Die folgenden Beispiele zeigen, wie Eigenschaften für ein Glyphs-Objekt in Extensible Application Markup Language (XAML) definiert werden. Das Glyphs-Objekt stellt die Ausgabe von einem GlyphRun in XAML dar. In diesen Beispielen wird davon ausgegangen, dass die Schriftarten Arial, Courier New und Times New Roman auf dem lokalen Computer im Ordner C:\WINDOWS\Fonts installiert sind.
<!-- The example shows how to use a Glyphs object. -->
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel Background="PowderBlue">
<Glyphs
FontUri = "C:\WINDOWS\Fonts\TIMES.TTF"
FontRenderingEmSize = "100"
StyleSimulations = "BoldSimulation"
UnicodeString = "Hello World!"
Fill = "Black"
OriginX = "100"
OriginY = "200"
/>
</StackPanel>
</Page>
Verwenden von DrawGlyphRun
Wenn Sie über ein benutzerdefiniertes Steuerelement verfügen und Symbole rendern möchten, verwenden Sie die DrawGlyphRun-Methode.
WPF stellt durch die Verwendung des FormattedText-Objekts auch Dienste auf einer untergeordneten Ebene zur benutzerdefinierten Textformatierung bereit. Sie können in Windows Presentation Foundation (WPF) Text am effizientesten rendern, indem Sie unter Verwendung von Glyphs und GlyphRun den Textinhalt auf der Symbolebene generieren. Diese Funktionsfähigkeit hat jedoch den Verlust der benutzerfreundlichen RTF-Formatierung zur Folge, die in den Windows Presentation Foundation (WPF)-Steuerelementen, z. B. in TextBlock und FlowDocument, integriert ist.
FormattedText-Objekt
Das FormattedText-Objekt ermöglicht das Zeichnen von mehrzeiligem Text, in dem jedes Zeichen einzeln formatiert werden kann. Weitere Informationen finden Sie unter Zeichnen von formatiertem Text.
Wenn Sie formatierten Text erstellen möchten, rufen Sie den FormattedText-Konstruktor auf, um ein FormattedText-Objekt zu erstellen. Nachdem Sie die formatierte Anfangs-Textzeichenfolge erstellt haben, können Sie eine Reihe von Formatierungsstilen anwenden. Wenn Ihre Anwendung ein eigenes Layout implementiert, sollten Sie das FormattedText-Objekt und kein Steuerelement, wie z. B. das TextBlock-Element, verwenden. Weitere Informationen über das FormattedText-Objekt finden Sie unter Zeichnen von formatiertem Text.
Das FormattedText-Objekt stellt Textformatierungsfunktionen auf einer untergeordneten Ebene bereit. Sie können mehrere Formatierungsstile auf ein oder mehrere Zeichen anwenden. Sie könnten z. B. sowohl die SetFontSize-Methode als auch die SetForegroundBrush-Methode aufrufen, um die Formatierung der ersten fünf Zeichen im Text zu ändern.
Im folgenden Codebeispiel wird ein FormattedText-Objekt erstellt und gerendert.
Protected Overrides Sub OnRender(ByVal drawingContext As DrawingContext)
Dim testString As String = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor"
' Create the initial formatted text string.
Dim formattedText As New FormattedText(testString, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, New Typeface("Verdana"), 32, Brushes.Black)
' Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
formattedText.MaxTextWidth = 300
formattedText.MaxTextHeight = 240
' Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
' The font size is calculated in terms of points -- not as device-independent pixels.
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5)
' Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
formattedText.SetFontWeight(FontWeights.Bold, 6, 11)
' Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
formattedText.SetForegroundBrush(New LinearGradientBrush(Colors.Orange, Colors.Teal, 90.0), 6, 11)
' Use an Italic font style beginning at the 28th character and continuing for 28 characters.
formattedText.SetFontStyle(FontStyles.Italic, 28, 28)
' Draw the formatted text string to the DrawingContext of the control.
drawingContext.DrawText(formattedText, New Point(10, 0))
End Sub
protected override void OnRender(DrawingContext drawingContext)
{
string testString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor";
// Create the initial formatted text string.
FormattedText formattedText = new FormattedText(
testString,
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Verdana"),
32,
Brushes.Black);
// Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
formattedText.MaxTextWidth = 300;
formattedText.MaxTextHeight = 240;
// Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
// The font size is calculated in terms of points -- not as device-independent pixels.
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5);
// Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
formattedText.SetFontWeight(FontWeights.Bold, 6, 11);
// Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
formattedText.SetForegroundBrush(
new LinearGradientBrush(
Colors.Orange,
Colors.Teal,
90.0),
6, 11);
// Use an Italic font style beginning at the 28th character and continuing for 28 characters.
formattedText.SetFontStyle(FontStyles.Italic, 28, 28);
// Draw the formatted text string to the DrawingContext of the control.
drawingContext.DrawText(formattedText, new Point(10, 0));
}
FlowDocument-, TextBlock- und Label-Steuerelement
WPF enthält mehrere Steuerelemente, um Text auf dem Bildschirm zeichnen zu können. Jedes Steuerelement zielt auf ein anderes Szenario ab und verfügt über individuelle Features und Einschränkungen.
FlowDocument wirkt sich mehr als TextBlock oder Label auf die Leistung aus
Im Allgemeinen sollte das TextBlock-Element verwendet werden, wenn eine eingeschränkte Textunterstützung erforderlich ist, z. B. ein kurzer Satz in einer user interface (UI). Label kann verwendet werden, wenn nur ein Minimum an Textunterstützung erforderlich ist. Das FlowDocument-Element ist ein Container für Flussdokumente, die umfangreiche Inhaltspräsentationen unterstützen, und wirkt sich demzufolge mehr auf die Leistung aus als das TextBlock-Steuerelement oder das Label-Steuerelement.
Weitere Informationen zu FlowDocument finden Sie unter Übersicht über Flussdokumente.
Vermeiden der Verwendung von TextBlock in FlowDocument
Das TextBlock-Element wird aus dem UIElement abgeleitet. Das Run-Element wird aus dem TextElement abgeleitet, das mit weniger Aufwand verwendet werden kann als ein Objekt, das vom UIElement abgeleitet ist. Verwenden Sie nach Möglichkeit Run statt TextBlock für die Anzeige von Textinhalt in einem FlowDocument.
Im folgenden Markupbeispiel werden zwei Methoden veranschaulicht, um Textinhalt in einem FlowDocument festzulegen:
<FlowDocument>
<!-- Text content within a Run (more efficient). -->
<Paragraph>
<Run>Line one</Run>
</Paragraph>
<!-- Text content within a TextBlock (less efficient). -->
<Paragraph>
<TextBlock>Line two</TextBlock>
</Paragraph>
</FlowDocument>
Vermeiden der Verwendung von Run zum Festlegen von Texteigenschaften
Im Allgemeinen ist die Verwendung von Run in einem TextBlock ressourcenintensiver als die Nichtverwendung eines expliziten Run-Objekts. Wenn Sie Run zum Festlegen von Texteigenschaften verwenden, legen Sie diese Eigenschaften stattdessen direkt im TextBlock fest.
Im folgenden Markupbeispiel werden diese beiden Methoden veranschaulicht, um eine Texteigenschaft (in diesem Fall die FontWeight-Eigenschaft) festzulegen:
<!-- Run is used to set text properties. -->
<TextBlock>
<Run FontWeight="Bold">Hello, world</Run>
</TextBlock>
<!-- TextBlock is used to set text properties, which is more efficient. -->
<TextBlock FontWeight="Bold">
Hello, world
</TextBlock>
In der folgenden Tabelle wird der Aufwand für das Anzeigen von 1000 TextBlock-Objekten mit und ohne explizite Angabe von Run aufgezeigt.
TextBlock-Typ |
Erstellungszeit (ms) |
Renderzeit (ms) |
---|---|---|
Festlegen von Texteigenschaften mit Run |
146 |
540 |
Festlegen von Texteigenschaften mit TextBlock |
43 |
453 |
Vermeiden der Datenbindung an die Label.Content-Eigenschaft
Stellen Sie sich ein Szenario mit einem Label-Objekt vor, das häufig von einer String-Quelle aktualisiert wird. Wenn Sie für die Content-Eigenschaft des Label-Elements eine Datenbindung an das String-Quellobjekt durchführen, kann dies zu einem Leistungsabfall führen. Bei jedem Aktualisieren der Quelle String wird das alte String-Objekt verworfen und ein neues String-Objekt erstellt. Der Grund dafür ist, dass ein String-Objekt unveränderlich ist. Dies führt wiederum dazu, dass der ContentPresenter des Label-Objekts den alten Inhalt verwirft und den neuen Inhalt generiert, um das neue String-Objekt anzuzeigen.
Die Lösung für dieses Problem ist einfach. Wenn für Label kein benutzerdefinierter ContentTemplate-Wert festgelegt ist, ersetzen Sie Label mit einem TextBlock und stellen für dessen Text-Eigenschaft eine Datenbindung an die Quellzeichenfolge her.
Datengebundene Eigenschaft |
Aktualisierungszeit (ms) |
---|---|
Label.Content |
835 |
TextBlock.Text |
242 |
Link
Das Hyperlink-Objekt stellt ein fortlaufendes Inhaltselement auf Inlineebene dar, das Ihnen das Hosten von Links im fortlaufenden Inhalt ermöglicht.
Kombinieren von Links in einem TextBlock-Objekt
Sie können die Verwendung mehrerer Hyperlink-Elemente optimieren, indem Sie sie zusammen in einem TextBlock gruppieren. Auf diese Weise können Sie die Anzahl der in Ihrer Anwendung zu erstellenden Objekte minimieren. So können Sie beispielsweise mehrere Links wie folgt anzeigen:
MSN Home | Mein MSN
Im folgenden Markupbeispiel werden mehrere TextBlock-Elemente veranschaulicht, die zur Anzeige der Links verwendet werden:
<!-- Hyperlinks in separate TextBlocks. -->
<TextBlock>
<Hyperlink TextDecorations="None" NavigateUri="https://www.msn.com">MSN Home</Hyperlink>
</TextBlock>
<TextBlock Text=" | "/>
<TextBlock>
<Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>
Im folgenden Markupbeispiel wird eine effizientere Möglichkeit zur Anzeige der Links aufgezeigt. In diesem Fall wird nur ein einzelnes TextBlock-Element verwendet:
<!-- Hyperlinks combined in the same TextBlock. -->
<TextBlock>
<Hyperlink TextDecorations="None" NavigateUri="https://www.msn.com">MSN Home</Hyperlink>
<Run Text=" | " />
<Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>
Anzeigen von unterstrichenen Links nur für MouseEnter-Ereignisse
Ein TextDecoration-Objekt kann als eine visuelle Verzierung dem Text hinzugefügt werden, wobei dessen Instanziierung zu einer erheblichen Bindung von Ressourcen führen kann. Wenn Sie Hyperlink-Elemente häufig einsetzen, sollten Sie einen Unterstrich nur anzeigen, wenn Sie ein Ereignis, z. B. das MouseEnter-Ereignis, auslösen. Weitere Informationen finden Sie unter Gewusst wie: Verwenden einer Textdekoration mit einem Link.
Link-Anzeige bei MouseEnter-Ereignis
Im folgenden Markupbeispiel wird ein Hyperlink mit und ohne Unterstreichung definiert:
<!-- Hyperlink with default underline. -->
<Hyperlink NavigateUri="https://www.msn.com">
MSN Home
</Hyperlink>
<Run Text=" | " />
<!-- Hyperlink with no underline. -->
<Hyperlink Name="myHyperlink" TextDecorations="None"
MouseEnter="OnMouseEnter"
MouseLeave="OnMouseLeave"
NavigateUri="https://www.msn.com">
My MSN
</Hyperlink>
In der folgenden Tabelle werden die Leistungseinbußen für das Anzeigen von 1000 Hyperlink-Elementen mit und ohne Unterstreichung aufgezeigt.
Link |
Erstellungszeit (ms) |
Renderzeit (ms) |
---|---|---|
Mit Unterstreichung |
289 |
1130 |
Ohne Unterstreichung |
299 |
776 |
Textformatierungsfeatures
WPF stellt Rich-Text-Formatierungsdienste bereit, z. B. automatische Silbentrennungen. Diese Dienste wirken sich möglicherweise auf die Anwendungsleistung aus und sollten nur dann verwendet werden, wenn sie benötigt werden.
Vermeiden von unnötiger Verwendung der Silbentrennung
Die automatische Silbentrennung findet in Textzeilen die entsprechenden Trennpositionen und ermöglicht zusätzliche Trennpositionen in den Zeilen von TextBlock-Objekten und FlowDocument-Objekten. Standardmäßig ist die automatische Silbentrennung in diesen Objekten deaktiviert. Sie können dieses Feature aktivieren, indem Sie die IsHyphenationEnabled-Eigenschaft des Objekts auf true festlegen. Die Aktivierung dieses Features führt jedoch dazu, dass WPF die Component Object Model (COM)-Interoperabilität initiiert, was sich auf die Anwendungsleistung auswirken kann. Es wird empfohlen, dass Sie die automatische Silbentrennung nur verwenden, wenn Sie sie benötigen.
Sorgfältiges Verwenden von Figure-Elementen
Ein Figure-Element stellt einen Teil eines fortlaufenden Inhalts dar, das in einer Inhaltsseite absolut positioniert werden kann. In einigen Fällen verursacht ein Figure-Element die automatische Neuformatierung einer gesamten Seite, wenn die Position des Elements mit dem im Layout bereits ausgerichteten Inhalt kollidiert. Sie können die Möglichkeit einer unnötigen Neuformatierung minimieren, indem Sie entweder die aufeinanderfolgenden Figure-Elemente gruppieren oder sie in einem festen Seitenszenario am Anfang des Inhalts deklarieren.
Optimaler Absatz
Mit dem Feature für das optimale Absatzlayout werden Absätze in einem FlowDocument-Objekt so formatiert, dass die Leerräume möglichst gleichmäßig verteilt werden. Standardmäßig ist das Feature für das optimale Absatzlayout deaktiviert. Sie können dieses Feature aktivieren, indem Sie die IsOptimalParagraphEnabled-Eigenschaft des Objekts auf true festlegen. Die Aktivierung dieses Features kann sich jedoch auf die Anwendungsleistung auswirken. Es wird empfohlen, dass Sie das Feature für das optimale Absatzlayout nur verwenden, wenn Sie es benötigen.
Siehe auch
Konzepte
Optimieren der WPF-Anwendungsleistung
Optimieren der Leistung: Vorteile der Hardware nutzen
Optimieren der Leistung: Layout und Entwurf
Optimieren der Leistung: 2D-Grafiken und Bildverarbeitung
Optimieren der Leistung: Objektverhalten
Optimieren der Leistung: Anwendungsressourcen