Optimizar el rendimiento: Texto

WPF incluye compatibilidad con la presentación de contenido de texto mediante controles de user interface (UI) de características enriquecidas. En general, puede dividir la representación de texto en tres capas:

  1. Utilizar directamente los objetos Glyphs y GlyphRun.

  2. Utilizar el objeto FormattedText.

  3. Utilizar controles de alto nivel, como los objetos TextBlock y FlowDocument.

En este tema se proporcionan recomendaciones para mejorar el rendimiento de la representación de texto.

Este tema contiene las secciones siguientes.

  • Representar texto en el nivel de glifos
  • Objeto FormattedText
  • Controles FlowDocument, TextBlock y Label
  • Hipervínculo
  • Características de formato de texto
  • Temas relacionados

Representar texto en el nivel de glifos

Windows Presentation Foundation (WPF) proporciona compatibilidad con texto avanzado que incluye marcado de nivel de glifos con acceso directo a Glyphs para los clientes que desean interceptar y conservar el texto después de darle formato. Estas características proporcionan compatibilidad vital para los distintos requisitos de representación de texto de cada uno de los escenarios siguientes.

  • Presentación en pantalla de documentos de formato fijo.

  • Escenarios de impresión.

    • Extensible Application Markup Language (XAML) como lenguaje de dispositivos de impresión.

    • Microsoft XPS Document Writer.

    • Controladores de impresora anteriores, salida de aplicaciones de Win32 en formato fijo.

    • Formato de colas de impresión.

  • Representación de documentos de formato fijo, incluidos clientes de versiones anteriores de Windows y otros dispositivos informáticos.

NotaNota

Glyphs y GlyphRun se han diseñado para escenarios de presentación e impresión de documentos de formato fijo.Windows Presentation Foundation (WPF) proporciona varios elementos para escenarios generales de diseño e user interface (UI) como Label y TextBlock.Para obtener más información sobre los escenarios de diseño e UI, consulte Tipografía en WPF.

En los ejemplos siguientes se muestra cómo definir las propiedades de un objeto Glyphs en Extensible Application Markup Language (XAML). El objeto Glyphs representa la salida de GlyphRun en XAML. En los ejemplos se supone que las fuentes Arial, Courier New y Times New Roman están instaladas en la carpeta C:\WINDOWS\Fonts del equipo 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>

Utilizar DrawGlyphRun

Si tiene un control personalizado y desea representar glifos, utilice el método DrawGlyphRun.

WPF también proporciona servicios del nivel inferior para dar formato personalizado al texto mediante el objeto FormattedText. La manera más eficaz de representar texto en Windows Presentation Foundation (WPF) es generar el contenido de texto en el nivel de glifos mediante Glyphs y GlyphRun. Sin embargo, el costo de esta eficacia es la pérdida de las características de formato de texto enriquecido fáciles de usar integradas en los controles de Windows Presentation Foundation (WPF), como TextBlock y FlowDocument.

Objeto FormattedText

El objeto FormattedText permite dibujar texto con varias líneas, en el que se puede dar formato a cada carácter individualmente. Para obtener más información, consulte Dibujar texto con formato.

Para crear texto con formato, llame al constructor FormattedText para crear un objeto FormattedText. Una vez creada la cadena de texto con formato inicial, puede aplicarle varios estilos de formato. Si desea que la aplicación implemente su propio diseño, el objeto FormattedText es más adecuado que usar control, como TextBlock. Para obtener más información sobre el objeto FormattedText, vea Dibujar texto con formato.

El objeto FormattedText proporciona la función de formato de texto de bajo nivel. Puede aplicar varios estilos de formato a uno o más caracteres. Por ejemplo, podría llamar a los métodos SetFontSize y SetForegroundBrush para cambiar el formato de los cinco primeros caracteres del texto.

En el ejemplo de código siguiente se crea un objeto FormattedText y se representa.

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

Controles FlowDocument, TextBlock y Label

WPF incluye varios controles para dibujar texto en la pantalla. Cada control se destina a un escenario diferente y tiene su propia lista de características y limitaciones.

FlowDocument afecta al rendimiento más que TextBlock o Label

En general, el elemento TextBlock se debe usar cuando se necesita una compatibilidad de texto limitada, como una frase breve en una user interface (UI). Label se puede usar cuando se necesita una compatibilidad de texto mínima. El elemento FlowDocument es un contenedor para documentos dinámicos que admite presentación enriquecida de contenido y, por consiguiente, afecta más al rendimiento mayor que los controles TextBlock o Label.

Para obtener más información sobre FlowDocument, consulte Información general sobre documentos dinámicos.

Evitar el uso de TextBlock en FlowDocument

El elemento TextBlock se deriva de UIElement. El elemento Run se deriva de TextElement, cuyo uso consume menos recursos que un objeto derivado de UIElement. Siempre que sea posible, utilice Run en lugar de TextBlock para mostrar contenido de texto en FlowDocument.

En el ejemplo de marcado siguiente se muestran dos maneras de establecer contenido de texto dentro de 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>

Evitar el uso de Run para establecer propiedades de texto

En general, utilizar Run dentro de TextBlock constituye una carga mayor para el rendimiento que no utilizar un objeto Run explícito en absoluto. En lugar de utilizar Run para establecer propiedades de texto, establezca directamente esas propiedades en TextBlock.

En el ejemplo de marcado siguiente se muestran estas dos maneras de establecer una propiedad de texto; en este caso, la propiedad 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>

En la tabla siguiente se muestra el costo de mostrar 1000 objetos TextBlock con y sin un objeto Run explícito.

Tipo de TextBlock

Tiempo de creación (ms)

Tiempo de representación (ms)

Propiedades de texto de configuración de Run

146

540

Propiedades de texto de configuración de TextBlock

43

453

Evitar el enlace de datos a la propiedad Label.Content

Imagine un escenario donde hay un objeto Label que se actualiza con frecuencia a partir de un origen String. Al efectuar un enlace de datos de la propiedad Content del elemento Label al objeto de origen String, puede experimentar un rendimiento insuficiente. Cada vez que se actualiza el objeto String de origen, se descarta el objeto String anterior y se crea un nuevo objeto String. Dado que un objeto String es inmutable, no se puede modificar. Esto, a su vez, hace que el ContentPresenter del objeto Label descarte su contenido anterior y vuelva a generar nuevo contenido para mostrar el nuevo objeto String.

La solución a este problema es simple. Si Label no está establecido en un valor de ContentTemplate personalizado, reemplace Label con TextBlock y enlace los datos su propiedad Text a la cadena de origen.

Propiedad enlazada a datos

Tiempo de actualización (ms)

Label.Content

835

TextBlock.Text

242

Hipervínculo

El objeto Hyperlink es un elemento de contenido dinámico insertado que permite hospedar hipervínculos dentro del contenido dinámico.

Combinar hipervínculos en un solo objeto TextBlock

Puede optimizar el uso de varios elementos Hyperlink agrupándolos dentro del mismo TextBlock. Esto ayuda a minimizar el número de objetos que se crean en la aplicación. Por ejemplo, puede que desee mostrar varios hipervínculos, como los siguientes:

MSN Home | My MSN

En el ejemplo de marcado siguiente se muestran varios elementos TextBlock utilizados para mostrar los hipervínculos:

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

En el ejemplo de marcado siguiente se muestra una manera más eficaz de mostrar los hipervínculos; esta vez, se utiliza un solo 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>

Mostrar hipervínculos subrayados sólo en los eventos MouseEnter

Un objeto TextDecoration es una ornamentación visual que se puede agregar al texto; sin embargo, la creación de instancias puede afectar negativamente al rendimiento. Si realiza un uso excesivo de elementos Hyperlink, puede ser conveniente mostrar la línea de subrayado únicamente al desencadenar un evento, como el evento MouseEnter. Para obtener más información, consulte Cómo: Usar una decoración de texto con un hipervínculo.

Hipervínculo que aparece al desencadenar MouseEnter

Hipervínculos que muestran TextDecorations

En el ejemplo de marcado siguiente se muestra Hyperlink con y sin subrayado:

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

En la tabla siguiente se muestra el costo para el rendimiento de mostrar 1000 elementos Hyperlink con y sin un subrayado.

Hipervínculo

Tiempo de creación (ms)

Tiempo de representación (ms)

Con subrayado

289

1130

Sin subrayado

299

776

Características de formato de texto

WPF proporciona servicios de formato de texto enriquecido, como la inclusión automática de guiones de división. Estos servicios puede afectar negativamente al rendimiento de la aplicación y únicamente deben utilizarse cuando se necesiten.

Evitar el uso innecesario de guiones

La división automática con guiones busca los puntos de interrupción del guión en las líneas de texto y permite posiciones de salto de línea adicionales en los objetos TextBlock y FlowDocument. De manera predeterminada, la característica de división automática con guiones está deshabilitada en estos objetos. Puede habilitar esta característica estableciendo la propiedad IsHyphenationEnabled del objeto en true. Sin embargo, habilitar esta característica hace que WPF inicie la interoperabilidad con Component Object Model (COM), lo que puede afectar al rendimiento de la aplicación. Se recomienda no utilizar la división automática con guiones a menos que lo necesite.

Prestar atención al utilizar figuras

Un elemento Figure representa una parte de contenido dinámico que puede tener una posición absoluta dentro de una página de contenido. En algunos casos, una Figure puede hacer que se cambie automáticamente el formato de una página si su posición está en conflicto con el contenido que ya se ha dispuesto en la página. Puede minimizar la posibilidad de cambios de formato innecesarios agrupando los elementos Figure contiguos o declarándolos cerca de la parte superior del contenido en un escenario de tamaño de página fijo.

Párrafo óptimo

La característica de párrafo óptimo del objeto FlowDocument dispone los párrafos de modo que el espacio en blanco se distribuya del modo más uniforme posible. De manera predeterminada, la característica de párrafo óptimo está deshabilitada. Puede habilitar esta característica estableciendo la propiedad IsOptimalParagraphEnabled del objeto en true. Sin embargo, habilitar esta característica afecta al rendimiento de la aplicación. Se recomienda no utilizar la característica de párrafo óptimo a menos que lo necesite.

Vea también

Conceptos

Optimizar WPF: Rendimiento de aplicaciones

Planear para mejorar el rendimiento de aplicaciones

Optimizar el rendimiento: Aprovechar el hardware

Optimizar el rendimiento: Presentación y diseño

Optimizar el rendimiento: Imágenes y gráficos 2D

Optimizar el rendimiento: Comportamiento de objetos

Optimizar el rendimiento: Recursos de aplicación

Optimizar el rendimiento: Enlace de datos

Optimizar el rendimiento: Otras recomendaciones