Share via


Otimizando o desempenho: Texto

WPF inclui suporte para a apresentação do conteúdo de texto através do uso de controles ricos em recursos de interface do usuário (UI). Em geral você pode dividir a renderização de texto em três camadas:

  1. Usando os objetos Glyphs e GlyphRun diretamente.

  2. Usando o objeto FormattedText.

  3. Usando controles de alto nível, como os objetos TextBlock e FlowDocument.

Este tópico fornece recomendações de desempenho de renderização de texto.

Este tópico contém as seguintes seções.

  • Renderização de Texto no Nível de Glifos
  • Objeto FormattedText
  • FlowDocument, TextBlock e Label Controls
  • Hiperlink
  • Recursos de formatação de texto
  • Tópicos relacionados

Renderização de Texto no Nível de Glifos

Windows Presentation Foundation (WPF) fornece suporte avançado de texto incluindo marcação em nível de glifos com acesso direto a Glyphs para clientes que desejam interceptar e persistir texto após a formatação. Esses recursos oferecem suporte crítico aos diferentes requisitos de renderização de texto em cada um dos seguintes cenários.

  • Tela de exibição de documentos de formato fixo.

  • Cenários de impressão.

    • Extensible Application Markup Language (XAML) como um idioma de dispositivo de impressora.

    • Microsoft XPS Document Writer.

    • Drivers anteriores de impressora, saídas de aplicativos Win32 para o formato fixo.

    • Formato de impressão em spool.

  • Representação do documento de formato fixo, incluindo clientes para versões anteriores do Windows e outros dispositivos de computação.

ObservaçãoObservação:

Glyphs e GlyphRun são projetados para cenários de impressão e apresentação do documento de formato fixo. Windows Presentation Foundation (WPF) fornece vários elementos de layout geral e interface do usuário (UI) cenários sistema autônomo Label e TextBlock. Para obter mais informações sobre layouts e cenários de UI, consulte o Tipografia em Windows Presentation Foundation.

Os exemplos a seguir mostram como definir propriedades para um objeto Glyphs no Extensible Application Markup Language (XAML). O objeto Glyphs representa a saída de um GlyphRun no XAML. Os exemplos assumem que as fontes Arial, Courier New e Times New Roman estão instaladas na pasta C:\WINDOWS\Fonts do computador local.

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

Usando DrawGlyphRun

Se você tiver controle personalizado e desejar renderizar glifos, use o método DrawGlyphRun.

WPF também fornece serviços de baixo nível para formatação personalizada de texto por meio do uso do objeto FormattedText. A maneira mais eficiente de renderizar texto em Windows Presentation Foundation (WPF) é gerar conteúdo de texto no nível de glifo usando Glyphs e GlyphRun. No entanto, o custo dessa eficiência é a perda de facilidade no uso de formatação rica de texto, que são recursos internos de controles Windows Presentation Foundation (WPF), tal como TextBlock e FlowDocument.

Objeto FormattedText

O objeto FormattedText permite que você desenhe texto de várias linhas, no qual cada caractere no texto pode ser formatado individualmente. Para obter mais informações, consulte Drawing Formatted Text.

Para criar texto formatado, chame o construtor FormattedText para criar um objeto FormattedText. Depois de criar a sequência de caracteres de texto formatado inicial, você pode aplicar uma variedade de estilos de formatação. Se seu aplicativo deseja implementar seu próprio layout, o objeto FormattedText é um melhor opção do que usar um controle, como TextBlock. Para mais informações sobre o objeto FormattedText, veja Drawing Formatted Text.

O objeto FormattedText fornece a capacidade de formatação de texto em baixo nível. Você pode aplicar diversos estilos de formatação a um ou mais caracteres. Por exemplo, você poderia chamar tanto o método SetFontSize quanto o método SetForegroundBrush para alterar a formatação dos cinco primeiros caracteres no texto.

O exemplo de código a seguir cria um objeto FormattedText e renderiza-o.

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 e Label Controls

WPF inclui vários controles para desenhar texto na tela. Cada controle é almejado a um cenário diferente e tem sua própria lista de características e limitações.

FlowDocument impacta o desempenho mais que TextBlock ou Label

Em geral, a TextBlock elemento deve ser usado quando o suporte limitado de texto é necessário, por exemplo, uma breve frase em um interface do usuário (UI). Label pode ser usado quando a quantidade mínima de texto de suporte é necessária. O elemento FlowDocument é um contêiner para documentos re-flowable que suportam apresentação rica do conteúdo, e portanto tem um impacto de desempenho maior do que usar os controles TextBlock ou Label.

Para obter mais informações sobre FlowDocument, consulte: Flow Document Overview.

Evite usar TextBlock em FlowDocument

O elemento TextBlock derivado de UIElement. O elemento Run é derivado de TextElement, que é menos caro do que usar um objeto derivado de UIElement. Quando possível, use Run em vez de TextBlock para exibir o conteúdo de texto em um FlowDocument.

O exemplo a seguir de marcação ilustra duas maneiras de definir conteúdo de texto em um 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>

Evite usar Run para definir propriedades de texto

Em geral, usar um Run em um TextBlock é mais custoso em termos de desempenho do que não usar qualquer objeto Run explícito. Se você estiver usando um Run para definir propriedades de texto, defina essas propriedades diretamente na TextBlock em vez disso.

O exemplo a seguir de marcação ilustra essas duas maneiras de definir uma propriedade de texto, nesse caso, a propriedade 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>

A tabela a seguir mostra o custo de exibir 1000 objetos TextBlock com e sem um Run explícito.

Tipo TextBlock

Tempo de criação (ms)

Tempo de renderização (ms)

Propriedades de configuração de texto Run

146

540

Propriedades de configuração de texto TextBlock

43

453

Evitar ligação de dados à propriedade Label.Content

Imagine um cenário em que você tenha um objeto Label que é atualizado com frequência a partir de uma String fonte. Ao fazer a associação de dados da propriedade Content do elemento Label ao objeto String fonte, você pode enfrentar um desempenho ruim. Sempre que a String fonte é atualizada, o objeto String antigo é descartado e um novo String será recriado — como um objeto String é imutável, ele não pode ser modificado. Isso, por sua vez, faz com que o ContentPresenter do objeto Label descarte seu conteúdo antigo e gere novamente o novo conteúdo para exibir a nova String.

A solução para esse problema é simples. Se o Label não é definido como um valor ContentTemplate personalizado, substitua o Label com um TextBlock e vincule sua propriedade Text à string fonte.

Propriedade dados vinculados

Tempo de atualização (ms)

Label.Content

835

TextBlock.Text

242

O objeto Hyperlink é um elemento de conteúdo de nível interno que permite você ter hiperlinks dentro do conteúdo de fluxo.

Você pode otimizar o uso de vários elementos Hyperlink agrupando-os no mesmo TextBlock. Isso ajuda a minimizar o número de objetos criados em seu aplicativo. Por exemplo, convém exibir vários hyperlinks, como o seguinte:

Início MSN | Meu MSN

O exemplo a seguir de marcação mostra vários elementos TextBlock usados para exibir os hyperlinks:

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

O exemplo a seguir de marcação mostra uma maneira mais eficiente de exibir os hyperlinks, desta vez, usando um único TextBlock:

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

Um objeto TextDecoration é um ornamento visual que você pode adicionar ao texto; no entanto, sua instanciação pode ser custosa em termos de desempenho. Se você fizer uso extensivo de elementos Hyperlink, considere mostrar um sublinhado somente quando ativando um evento, tal como o evento MouseEnter. Para obter mais informações, consulte Como: Use a Text Decoration with a Hyperlink.

Hyperlink aparecendo em MouseEnter

Hiperlinks exibindo TextDecorations

O exemplo a seguir de marcação mostra um Hyperlink definido com e sem sublinhado:

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

A tabela a seguir mostra o custo de desempenho de exibir 1000 elementos Hyperlink com e sem sublinhado.

Hiperlink

Tempo de criação (ms)

Tempo de renderização (ms)

Com sublinhado

289

1130

Sem sublinhado

299

776

Recursos de formatação de texto

WPF fornece serviços de formatação rica de texto, tal como hifenizações. Esses serviços podem afetar o desempenho do aplicativo e devem ser usados somente quando necessário.

Evitar o uso desnecessário de hifenização

A hifenização automática localiza pontos de interrupção nas linhas de texto para inserir hífens, e permite posições adicionais de quebra de linhas nos objetos TextBlock e FlowDocument. Por padrão, o recurso de hifenização automática está desativado nesses objetos. Você pode ativar esse recurso definindo a propriedade IsHyphenationEnabled do objeto como true. No entanto, habilitar esse recurso faz com que WPF inicie a interoperabilidade Modelo de objeto componente (COM), que pode impactar o desempenho do aplicativo. É recomendável que você não use a hifenização automática a menos que necessário.

Usar figuras cuidadosamente

Um elemento Figure representa uma parte do conteúdo de fluxo que pode ser posicionado absolutamente dentro de uma página de conteúdo. Em alguns casos, um Figure pode causar que uma página inteira seja reformatada automaticamente se a sua posição colidir com conteúdo que já foi posicionado. Você pode minimizar a possibilidade de reformatação desnecessária agrupamento elementos Figure próximos uns dos outros, ou declará-los na parte superior do conteúdo em um cenário tamanho fixo de página.

Parágrafo otimizado

O recurso parágrafo otimizado do objeto FlowDocument dispõe parágrafos para que o espaço em branco seja distribuído tão uniformemente quanto possível. Por padrão, o recurso de parágrafo otimizado é desativado. Você pode ativar esse recurso definindo a propriedade IsOptimalParagraphEnabled do objeto como true. No entanto, ativar este recurso afeta o desempenho do aplicativo. É recomendável que você não use o recurso de parágrafo otimizado a menos que necessário.

Consulte também

Conceitos

Optimizing WPF Application Performance

Planejando para desempenho de aplicativos

Otimizando o desempenho: Levando vantagens de hardware

Otimizando o desempenho: Layout and Design

Otimizando o desempenho: 2D Graphics and Imaging

Otimizando o desempenho: Comportamento de objeto

Otimizando o desempenho: Recursos do aplicativo

Otimizando o desempenho: Ligação de Dados

Otimizando o desempenho: Outras recomendações

Ferramentas de Desempenho e Recursos do WPF