Freigeben über


Optimieren der Leistung: Text

WPF bietet Unterstützung für die Darstellung von Textinhalten unter Verwendung von funktionsreichen UI-Steuerelementen. Im Allgemeinen können Sie das Rendern von Text in drei Ebenen unterteilen:

  1. Verwenden Sie die Glyphs- und GlyphRun-Objekte direkt.

  2. Verwenden des FormattedText Objekts.

  3. Verwenden von hochwertigen Steuerelementen, z. B. den TextBlock und FlowDocument Objekten.

Dieses Thema enthält Empfehlungen zur Verbesserung der Leistung des Textrenderings.

Rendern von Text auf Glyphenebene

Windows Presentation Foundation (WPF) bietet erweiterte Unterstützung für Text, einschließlich Markup auf Glyphenebene mit direktem Zugriff auf Glyphs für Kunden, die Text nach der Formatierung abfangen und beibehalten möchten. Diese Features bieten wichtige Unterstützung für die verschiedenen Anforderungen an das Rendern von Text in jedem der folgenden Szenarien.

  • Bildschirmanzeige von Dokumenten mit festem Format

  • Druckszenarios

    • Extensible Application Markup Language (XAML) als Gerätedruckersprache.

    • Microsoft XPS-Dokument-Writer.

    • Ältere Druckertreiber geben Win32-Anwendungen in einem festen Format aus.

    • Druckerspoolformat

  • Dokumentdarstellung im festen Format, einschließlich Clients für frühere Versionen von Windows und anderen Computergeräten.

Hinweis

Glyphs und GlyphRun sind für Dokumentpräsentations- und Druckszenarien mit fester Formatierung ausgelegt. WPF stellt mehrere Elemente für allgemeine Layout- und Benutzeroberflächenszenarien bereit, wie z. B. Label und TextBlock. Weitere Informationen zu Layout- und Benutzeroberflächenszenarios finden Sie unter Typografie in WPF.

Die folgenden Beispiele zeigen, wie Eigenschaften für ein Glyphs Objekt in XAML definiert werden. In den Beispielen wird davon ausgegangen, dass die Schriftarten Arial, Courier New und Times New Roman im Ordner "C:\WINDOWS\Fonts" auf dem lokalen Computer installiert sind.

<!-- The example shows how to use a Glyphs object. -->
<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://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 benutzerdefinierte Steuerelemente verfügen und Glyphen rendern möchten, verwenden Sie die DrawGlyphRun Methode.

WPF bietet auch Dienste auf niedrigerer Ebene für benutzerdefinierte Textformatierungen über die Verwendung des FormattedText Objekts. Die effizienteste Methode zum Rendern von Text in Windows Presentation Foundation (WPF) ist das Generieren von Textinhalten auf Glyphenebene mithilfe Glyphs und GlyphRun. Jedoch kostet diese Effizienz den Verlust der einfach zu bedienenden Rich-Text-Formatierung, die integrierte Funktionen der Windows Presentation Foundation (WPF)-Steuerelemente wie TextBlock und FlowDocument sind.

FormattedText-Objekt

Mit dem FormattedText-Objekt können Sie mehrzeiligen Text zeichnen, in dem jedes Zeichen im Text einzeln formatiert werden kann. Weitere Informationen finden Sie unter "Erstellung formatierter Texte".

Rufen Sie zum Erstellen von formatiertem Text den FormattedText-Konstruktor auf, um ein FormattedText-Objekt zu erstellen. Nachdem Sie eine ursprünglich formatierte Textzeichenfolge erstellt haben, können Sie eine Reihe von Formatierungsstilen anwenden. Wenn Ihre Anwendung ein eigenes Layout implementieren möchte, ist das FormattedText Objekt besser geeignet als ein Steuerelement, wie z. B. TextBlock zu verwenden. Weitere Informationen zum FormattedText Objekt finden Sie unter Formatierten Text zeichnen.

Das FormattedText Objekt stellt eine Textformatierungsfunktion auf niedriger Ebene bereit. Sie können mehrere Formatvorlagen auf ein oder mehrere Zeichen anwenden. Sie können z. B. die methoden SetFontSize und SetForegroundBrush aufrufen, um die Formatierung der ersten fünf Zeichen im Text zu ändern.

Im folgenden Codebeispiel wird ein FormattedText Objekt erstellt und gerendert.

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));
}
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

FlowDocument-, TextBlock- und Label-Steuerelemente

WPF enthält mehrere Steuerelemente zum Zeichnen von Text auf dem Bildschirm. Jedes Steuerelement ist auf ein anderes Szenario ausgerichtet und verfügt über eine eigene Liste von Features und Einschränkungen.

FlowDocument wirkt sich auf die Leistung mehr als "TextBlock" oder "Label" aus.

Im Allgemeinen sollte das TextBlock-Element verwendet werden, wenn eine eingeschränkte Textunterstützung erforderlich ist, z. B. einen kurzen Satz auf einer Benutzeroberfläche. Label kann verwendet werden, wenn eine minimale Textunterstützung erforderlich ist. Das FlowDocument Element ist ein Container für umfließbare Dokumente, die eine umfassende Darstellung von Inhalten unterstützen, und hat daher eine größere Auswirkung auf die Leistung als die Verwendung der TextBlockLabel Steuerelemente.

Weitere Informationen zu FlowDocument finden Sie in der Übersicht über Flowdokumente.

Vermeiden der Verwendung von TextBlock in FlowDocument

Das TextBlock-Element wird von UIElement abgeleitet. Das Run Element wird von TextElement abgeleitet, das weniger kostenintensiv zu verwenden ist als ein von UIElement abgeleitetes Objekt. Verwenden Sie Run nach Möglichkeit anstelle von TextBlock zur Anzeige von Textinhalten in einem FlowDocument.

Das folgende Markupbeispiel veranschaulicht zwei Möglichkeiten zum Festlegen von Textinhalten in einem FlowDocument:

<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 Sie die Verwendung von "Ausführen" zum Einstellen der Texteigenschaften

Im Allgemeinen ist die Verwendung von Run in TextBlock leistungsintensiver als überhaupt die Verwendung eines expliziten Run-Objekts. Wenn Sie ein Run zum Festlegen von Texteigenschaften verwenden, legen Sie diese Eigenschaften stattdessen direkt auf dem TextBlock fest.

Im folgenden Markupbeispiel werden diese beiden Methoden zum Festlegen einer Texteigenschaft veranschaulicht, in diesem Fall die FontWeight Eigenschaft:

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

Die folgende Tabelle zeigt die Kosten für die Anzeige von 1000 TextBlock Objekten mit und ohne explizite Run.

TextBlock-Typ Erstellungszeit (ms) Renderzeit (ms)
Festlegen von Texteigenschaften ausführen 146 540
TextBlock-Konfigurieren der Texteigenschaften 43 453

Vermeiden der Datenbindung zu der Label.Content-Eigenschaft

Stellen Sie sich ein Szenario vor, in dem Sie ein Label Objekt haben, das häufig aus einer String Quelle aktualisiert wird. Wenn die Eigenschaft des Label-Elements Content an das Quellobjekt String gebunden wird, kann es zu schlechter Performance kommen. Jedes Mal, wenn die Quelle String aktualisiert wird, wird das alte String Objekt verworfen und ein neues String neu erstellt – da ein String Objekt unveränderlich ist, kann es nicht geändert werden. Dies wiederum bewirkt, dass das ContentPresenterLabel Objekt seinen alten Inhalt verwirft und neuen Inhalt generiert, um den neuen String anzuzeigen.

Die Lösung für dieses Problem ist einfach. Wenn der Label Wert nicht auf einen benutzerdefinierten ContentTemplate Wert festgelegt ist, ersetzen Sie das Label Element durch ein TextBlock und binden Sie seine Text Eigenschaft an die Quellzeichenfolge.

Datengebundene Eigenschaft Aktualisierungszeit (ms)
Label.Content 835
TextBlock.Text 242

Das Hyperlink-Objekt ist ein Element für fortlaufenden Inhalt auf Inlineebene, das Ihnen das Hosten von Links im fortlaufenden Inhalt ermöglicht.

Sie können die Verwendung mehrerer Hyperlink Elemente optimieren, indem Sie sie innerhalb desselben TextBlockgruppieren. Dadurch können Sie die Anzahl der Objekte minimieren, die Sie in Ihrer Anwendung erstellen. Sie können z. B. mehrere Hyperlinks anzeigen, z. B. die folgenden:

MSN Home | Mein MSN

Das folgende Markupbeispiel zeigt mehrere TextBlock Elemente, die zum Anzeigen der Hyperlinks verwendet werden:

<!-- Hyperlinks in separate TextBlocks. -->
<TextBlock>
  <Hyperlink TextDecorations="None" NavigateUri="http://www.msn.com">MSN Home</Hyperlink>
</TextBlock>

<TextBlock Text=" | "/>

<TextBlock>
  <Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>

Das folgende Markupbeispiel zeigt eine effizientere Möglichkeit zum Anzeigen der Hyperlinks, diesmal unter Verwendung eines einzelnen TextBlock:

<!-- Hyperlinks combined in the same TextBlock. -->
<TextBlock>
  <Hyperlink TextDecorations="None" NavigateUri="http://www.msn.com">MSN Home</Hyperlink>
  
  <Run Text=" | " />
  
  <Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>

Ein TextDecoration-Objekt ist eine visuelle Verzierung, die Sie einem Text hinzufügen können; jedoch kann es leistungintensiv sein, wenn es instanziert wird. Wenn Sie Hyperlink-Elemente umfassend nutzen, sollten Sie eine Unterstreichung nur dann anzeigen, wenn ein Ereignis ausgelöst wird, beispielsweise beim MouseEnter-Ereignis. Weitere Informationen finden Sie unter Angeben, ob ein Hyperlink unterstrichen wird.

Die folgende Abbildung zeigt, wie das MouseEnter-Ereignis den unterstrichenen Link auslöst:

Hyperlinks mit TextDecorations

Im folgenden Markupbeispiel wird ein mit und ohne Unterstreichung definierter Hyperlink gezeigt:

<!-- Hyperlink with default underline. -->
<Hyperlink NavigateUri="http://www.msn.com">
  MSN Home
</Hyperlink>

<Run Text=" | " />

<!-- Hyperlink with no underline. -->
<Hyperlink Name="myHyperlink" TextDecorations="None"
           MouseEnter="OnMouseEnter"
           MouseLeave="OnMouseLeave"
           NavigateUri="http://www.msn.com">
  My MSN
</Hyperlink>

Die folgende Tabelle zeigt die Leistungskosten für die Anzeige von 1000 Hyperlink Elementen mit und ohne Unterstreichung.

Hyperlink- Erstellungszeit (ms) Renderzeit (ms)
Mit Unterstreichung 289 1130
Ohne Unterstreichung 299 776

Textformatierungsfunktionen

WPF stellt Rich-Text-Formatierungsdienste bereit, z. B. automatische Silbentrennungen. Diese Dienste können sich auf die Anwendungsleistung auswirken und sollten nur bei Bedarf verwendet werden.

Vermeiden Sie unnötige Verwendung der Silbentrennung

Die automatische Silbentrennung findet Silbentrennungsstellen für Textzeilen und ermöglicht zusätzliche Umbruchpositionen für Zeilen in TextBlock und FlowDocument Elemente. Standardmäßig ist das Feature für die automatische Silbentrennung in diesen Objekten deaktiviert. Sie können dieses Feature aktivieren, indem Sie die IsHyphenationEnabled-Eigenschaft des Objekts auf festlegen true. Das Aktivieren dieses Features bewirkt jedoch, dass WPF die Com-Interoperabilität (Component Object Model) initiiert, was sich auf die Anwendungsleistung auswirken kann. Es wird empfohlen, die automatische Silbentrennung nur dann zu verwenden, wenn Sie sie benötigen.

Verwenden Sie Zahlen sorgfältig

Ein Figure Element stellt einen Teil des Flussinhalts dar, der innerhalb einer Inhaltsseite absolut positioniert werden kann. In einigen Fällen kann eine gesamte Seite automatisch neu formatiert werden, wenn ihre Position mit Inhalten kollidiert, die bereits angeordnet wurden. Sie können die Möglichkeit einer unnötigen Neuformatierung minimieren, indem Sie Figure Elemente nebeneinander gruppieren oder sie nahe am oberen Rand des Inhalts in einem Szenario mit fester Seitengröße deklarieren.

Optimaler Absatz

Die optimale Absatzfunktion des FlowDocument Objekts legt Absätze so fest, dass Leerraum so gleichmäßig wie möglich verteilt wird. Standardmäßig ist die optimale Absatzfunktion deaktiviert. Sie können diese Funktion aktivieren, indem Sie die IsOptimalParagraphEnabled Eigenschaft des Objekts auf true setzen. Das Aktivieren dieses Features wirkt sich jedoch auf die Anwendungsleistung aus. Es wird empfohlen, die optimale Absatzfunktion nicht zu verwenden, es sei denn, Sie benötigen es.

Siehe auch