Dela via


Optimera prestationsförmåga: Textinnehåll

WPF innehåller stöd för presentation av textinnehåll med hjälp av funktionsrika användargränssnittskontroller (UI). I allmänhet kan du dela upp textrendering i tre lager:

  1. Använd objekten Glyphs och GlyphRun direkt.

  2. Använda objektet FormattedText .

  3. Använda kontroller på hög nivå, till exempel objekten TextBlock och FlowDocument .

Det här avsnittet innehåller prestandarekommendationer för textåtergivning.

Återge text på Glyph-nivå

Windows Presentation Foundation (WPF) ger avancerat textstöd, inklusive markering på glyph-nivå med direkt åtkomst till Glyphs för kunder som vill fånga upp och bevara text efter formatering. Dessa funktioner ger kritiskt stöd för de olika kraven för textrendering i vart och ett av följande scenarier.

  • Skärmvisning av dokument med fast format.

  • Utskriftsscenarier.

    • XAML (Extensible Application Markup Language) som ett enhetsskrivarespråk.

    • Microsoft XPS-dokumentskrivare.

    • Tidigare skrivardrivrutiner, utdata från Win32-program till fast format.

    • Utskriftspoolformat.

  • Dokumentrepresentation med fast format, inklusive klienter för tidigare versioner av Windows och andra databehandlingsenheter.

Anmärkning

Glyphs och GlyphRun är utformade för scenarier med fast format för dokumentpresentation och utskrift. WPF innehåller flera element för scenarier med allmän layout och användargränssnitt(UI), till exempel Label och TextBlock. Mer information om layout- och användargränssnittsscenarier finns i Typografi i WPF.

I följande exempel visas hur du definierar egenskaper för ett Glyphs objekt i XAML. Exemplen förutsätter att teckensnitten Arial, Courier New och Times New Roman är installerade i mappen C:\WINDOWS\Fonts på den lokala datorn.

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

Använda DrawGlyphRun

Om du har anpassad kontroll och vill återge glyfer använder DrawGlyphRun du metoden .

WPF tillhandahåller också tjänster på lägre nivå för anpassad textformatering med hjälp av FormattedText objektet. Det mest effektiva sättet att återge text i Windows Presentation Foundation (WPF) är genom att generera textinnehåll på glyph-nivå med hjälp av Glyphs och GlyphRun. Kostnaden för den här effektiviteten är dock förlusten av lätt att använda RTF-formatering, som är inbyggda funktioner i WPF-kontroller (Windows Presentation Foundation), till exempel TextBlock och FlowDocument.

Formaterattextobjekt

Med objektet FormattedText kan du rita text med flera rader, där varje tecken i texten kan formateras individuellt. Mer information finns i Formatera Text i Ritningar.

Om du vill skapa formaterad text anropar du konstruktorn FormattedText för att skapa ett FormattedText objekt. När du har skapat den första formaterade textsträngen kan du använda ett intervall med formateringsformat. Om ditt program vill implementera sin egen layout är objektet FormattedText bättre än att använda en kontroll, till exempel TextBlock. Mer information om objektet finns i FormattedTextRita formaterad text .

Objektet FormattedText tillhandahåller textformatering på låg nivå. Du kan använda flera formateringsformat på ett eller flera tecken. Du kan till exempel anropa både metoderna SetFontSize och SetForegroundBrush för att ändra formateringen för de fem första tecknen i texten.

Följande kodexempel skapar ett FormattedText-objekt och renderar det.

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

WPF innehåller flera kontroller för att rita text på skärmen. Varje kontroll är riktad mot ett annat scenario och har en egen lista över funktioner och begränsningar.

FlowDocument påverkar prestanda mer än TextBlock eller etikett

I allmänhet bör TextBlock-elementet användas när begränsat textstöd krävs, till exempel en kort mening i ett användargränssnitt (UI). Label kan användas när minimalt textstöd krävs. Elementet FlowDocument är en container för omflödesbara dokument som stöder omfattande presentation av innehåll och därför har större prestandapåverkan än att använda TextBlock kontrollerna eller Label .

Mer information om FlowDocumentfinns i Översikt över flödesdokument.

Undvik att använda TextBlock i FlowDocument

Elementet TextBlock härleds från UIElement. Elementet Run härleds från TextElement, vilket är billigare att använda än ett UIElement-derived-objekt. Använd Run i stället för TextBlock när det är möjligt för att visa textinnehåll i en FlowDocument.

Följande markeringsexempel illustrerar två sätt att ange textinnehåll i en 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>

Undvik att använda Kör för att ange textegenskaper

I allmänhet är det mer prestandakrävande att använda en Run i en TextBlock än att inte använda ett explicit Run objekt alls. Om du använder en Run för att ange textegenskaper anger du dessa egenskaper direkt på i TextBlock stället.

Följande markeringsexempel illustrerar dessa två sätt att ange en textegenskap, i det här fallet egenskapen FontWeight :

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

I följande tabell visas kostnaden för att visa 1 000 TextBlock objekt med och utan en explicit Run.

TextBlock-typ Skapandetid (ms) återgivningstid (ms)
Textegenskaper för körningsinställning 146 540
TextBlock-inställning av textegenskaper 43 453

Undvik databindning till egenskapen Label.Content

Föreställ dig ett scenario där du har ett Label objekt som uppdateras ofta från en String källa. När data binder elementets LabelContent egenskap till String källobjektet, kan det uppstå dålig prestanda. Varje gång källan String uppdateras tas det gamla String objektet bort och en ny String återskapas– eftersom ett String objekt inte kan ändras kan det inte ändras. Detta gör i sin tur att ContentPresenter-objektet för Label tar bort sitt gamla innehåll och återskapar det nya innehållet för att visa det nya String.

Lösningen på det här problemet är enkel. Om Label inte är inställd på ett anpassat ContentTemplate-värde, ersätt Label med en TextBlock och databinda dess Text-egenskap till källsträngen.

Databunden egenskap Uppdateringstid (ms)
Label.Content 835
TextBlock.Text 242

** Objektet Hyperlink är ett flödesinnehållselement på infogad nivå som gör att du kan innehålla hyperlänkar i flödesinnehållet.

Du kan optimera användningen av flera Hyperlink element genom att gruppera dem inom samma TextBlock. Detta hjälper till att minimera antalet objekt som du skapar i ditt program. Du kanske till exempel vill visa flera hyperlänkar, till exempel följande:

MSN Home | Mitt MSN

Följande markeringsexempel visar flera TextBlock element som används för att visa hyperlänkarna:

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

Följande markeringsexempel visar ett effektivare sätt att visa hyperlänkarna, den här gången med hjälp av en enda 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>

Ett TextDecoration objekt är en visuell utsmyckning som du kan lägga till i text. Det kan dock vara prestandaintensivt att instansiera. Om du använder Hyperlink element i stor utsträckning kan du bara visa en understrykning när du utlöser en händelse, till exempel händelsen MouseEnter . Mer information finns i Ange om en hyperlänk är understruken.

Följande bild visar hur MouseEnter-händelsen utlöser den understrukna hyperlänken:

hyperlänkar som visar textdekorationer

Följande markeringsexempel visar ett Hyperlink definierat med och utan understrykning:

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

I följande tabell visas prestandakostnaden för att visa 1 000 Hyperlink element med och utan understrykning.

hyperlänk Skapandetid (ms) återgivningstid (ms)
Med understrykning 289 1130
Utan understrykning 299 776

Textformateringsfunktioner

WPF tillhandahåller RTF-formateringstjänster, till exempel automatiska avstavningar. Dessa tjänster kan påverka programmets prestanda och bör endast användas när det behövs.

Undvik onödig användning av avstavning

Automatisk avstavning hittar bindestrecksbrytningar för textrader och tillåter ytterligare brytpunkter för rader i TextBlock och FlowDocument objekt. Som standard är funktionen för automatisk avstavning inaktiverad i dessa objekt. Du kan aktivera den här funktionen genom att ange objektets egenskap IsHyphenationEnabled till true. Att aktivera den här funktionen gör dock att WPF initierar COM-samverkan (Component Object Model), vilket kan påverka programmets prestanda. Vi rekommenderar att du inte använder automatisk avstavning om du inte behöver det.

Använd siffror noggrant

Ett Figure element representerar en del av flödesinnehållet som kan placeras helt på en sida med innehåll. I vissa fall kan en Figure orsaka att en hel sida automatiskt formateras om dess position kolliderar med innehåll som redan har lagts fram. Du kan minimera risken för onödig omformatering genom att antingen gruppera Figure element bredvid varandra eller deklarera dem nära toppen av innehållet i ett scenario med fast sidstorlek.

Optimalt avsnitt

Den optimala styckefunktionen i FlowDocument objektet lägger ut stycken så att tomt utrymme fördelas så jämnt som möjligt. Som standard är den optimala styckefunktionen inaktiverad. Du kan aktivera den här funktionen genom att ange objektets IsOptimalParagraphEnabled egenskap till true. Om du aktiverar den här funktionen påverkas dock programmets prestanda. Vi rekommenderar att du inte använder den optimala styckefunktionen om du inte behöver den.

Se även