Ottimizzazione delle prestazioni: testo

WPF include il supporto per la presentazione di contenuto di testo tramite l'utilizzo dei controlli dell'user interface (UI) con funzionalità dettagliate. In generale, è possibile suddividere il rendering del testo in tre livelli:

  1. Utilizzo diretto degli oggetti Glyphs e GlyphRun.

  2. Utilizzo dell'oggetto FormattedText.

  3. Utilizzo di controlli di livello elevato, ad esempio TextBlock e FlowDocument.

In questo argomento vengono forniti i requisiti relativi alle prestazioni del rendering di testo.

Nel presente argomento sono contenute le seguenti sezioni.

  • Rendering di testo a livello di glifo
  • Oggetto FormattedText
  • Controlli FlowDocument, TextBlock e Label
  • Hyperlink
  • Funzionalità di formattazione del testo
  • Argomenti correlati

Rendering di testo a livello di glifo

In Windows Presentation Foundation (WPF) è disponibile supporto avanzato per il testo, incluso il markup a livello di glifo con accesso diretto a Glyphs per i clienti che desiderano intercettare e salvare in modo permanente il testo dopo la formattazione. Queste funzionalità forniscono un supporto critico per i diversi requisiti del rendering di testo in ognuno dei seguenti scenari.

  • Visualizzazione di documenti con formato fisso.

  • Scenari di stampa.

    • Extensible Application Markup Language (XAML) come linguaggio della stampante.

    • Microsoft XPS Document Writer.

    • Driver della stampante precedenti, restituiti dalle applicazioni Win32 nel formato fisso.

    • Formato di spooling della stampa.

  • Rappresentazione di documenti con formato fisso, inclusi i client per versioni precedenti di Windows e altri dispositivi di elaborazione.

NotaNota

Glyphs e GlyphRun sono progettati per scenari di presentazione e di stampa di documenti con formato fisso.In Windows Presentation Foundation (WPF) vengono forniti diversi elementi per il layout generale e gli scenari dell'user interface (UI), ad esempio Label e TextBlock.Per ulteriori informazioni sul layout e sugli scenari dell'UI, vedere Funzionalità tipografiche di WPF.

Negli esempi riportati di seguito viene illustrato come definire le proprietà per un oggetto Glyphs in Extensible Application Markup Language (XAML). L'oggetto Glyphs rappresenta l'output di un oggetto GlyphRun in XAML. Negli esempi si presuppone che i tipi di carattere Arial, Courier New e Times New Roman siano installati nella cartella C:\WINDOWS\Fonts sul computer locale.

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

Utilizzo di DrawGlyphRun

Se si dispone di un controllo personalizzato e si desidera eseguire il rendering dei glifi, utilizzare il metodo DrawGlyphRun.

In WPF sono inoltre disponibili servizi di livello più basso per la formattazione del testo personalizzato tramite l'utilizzo dell'oggetto FormattedText. Il modo più efficiente per eseguire il rendering del testo in Windows Presentation Foundation (WPF) è costituito dalla generazione di contenuto di testo a livello di glifo tramite Glyphs e GlyphRun. Tuttavia, il costo di questa efficienza è la perdita del formato RTF di facile utilizzo, funzionalità incorporate dei controlli Windows Presentation Foundation (WPF), ad esempio TextBlock e FlowDocument.

Oggetto FormattedText

L'oggetto FormattedText consente di creare testo su più righe, in cui ogni carattere può essere formattato singolarmente. Per ulteriori informazioni, vedere Disegno di testo formattato.

Per creare testo formattato, chiamare il costruttore FormattedText per creare un oggetto FormattedText. Dopo aver creato la stringa di testo formattato iniziale, è possibile applicare una gamma di stili di formattazione. Per implementare un layout personalizzato per l'applicazione, è più opportuno scegliere l'oggetto FormattedText piuttosto che utilizzare un controllo, ad esempio TextBlock. Per ulteriori informazioni sull'oggetto FormattedText, vedere Disegno di testo formattato.

L'oggetto FormattedText offre funzionalità di formattazione del testo di basso livello. È possibile applicare più stili di formattazione a uno o più caratteri. Ad esempio, è possibile chiamare entrambi i metodi SetFontSize e SetForegroundBrush per modificare la formattazione dei primi cinque caratteri nel testo.

Nell'esempio di codice riportato di seguito viene creato un oggetto FormattedText e ne viene eseguito il rendering.

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

Controlli FlowDocument, TextBlock e Label

WPF include più controlli per creare testo sullo schermo. Ogni controllo è destinato a uno scenario diverso e dispone di un proprio elenco di funzionalità e limitazioni.

Impatto maggiore sulle prestazioni di FlowDocument rispetto a TextBlock o Label

In genere, è opportuno utilizzare l'elemento TextBlock quando è necessario un supporto limitato del testo, ad esempio una breve frase in un'user interface (UI). Quando è necessario un supporto minimo del testo, è possibile utilizzare Label. L'elemento FlowDocument è un contenitore per documenti con flusso rinnovabile che supportano la presentazione dettagliata di contenuto e pertanto, ha un impatto maggiore sulle prestazioni rispetto ai controlli TextBlock o Label.

Per ulteriori informazioni su FlowDocument, vedere Cenni preliminari sui documenti dinamici.

Evitare l'utilizzo di TextBlock in FlowDocument

L'elemento TextBlock deriva da UIElement. L'elemento Run deriva da TextElement, il cui utilizzo è meno dispendioso rispetto a un oggetto derivato da UIElement. Quando possibile, utilizzare Run anziché TextBlock per la visualizzazione di contenuto di testo in un oggetto FlowDocument.

Nell'esempio di markup riportato di seguito vengono illustrate due modalità per impostare il contenuto di testo in un oggetto 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>

Evitare l'utilizzo di Run per impostare le proprietà di testo

In generale, l'utilizzo di Run all'interno di TextBlock è più impegnativo in termini di prestazioni rispetto al mancato utilizzo di un oggetto Run esplicito. Se si utilizza Run per impostare le proprietà di testo, impostare tali proprietà direttamente in TextBlock.

Nell'esempio di markup riportato di seguito vengono illustrate queste due modalità per l'impostazione di una proprietà di testo, in questo caso 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>

Nella tabella riportata di seguito viene illustrato il costo della visualizzazione di 1000 oggetti TextBlock con e senza un oggetto Run esplicito.

Tipo TextBlock

Durata della creazione (ms)

Durata del rendering (ms)

Proprietà di testo per l'impostazione di Run

146

540

Proprietà di testo per l'impostazione di TextBlock

43

453

Evitare l'associazione di dati alla proprietà Label.Content

Si immagini uno scenario in cui si dispone di un oggetto Label frequentemente aggiornato da un'origine String. Quando si esegue l'associazione dati della proprietà Content dell'elemento Label all'oggetto di origine String, le prestazioni possono risultare insufficienti. A ogni aggiornamento dell'oggetto String di origine, l'oggetto String precedente viene ignorato e ne viene ricreato uno nuovo. Poiché String è immutabile, non può essere modificato. Di conseguenza, tramite l'oggetto ContentPresenter dell'oggetto Label verrà eliminato il contenuto precedente e verrà rigenerato nuovo contenuto per visualizzare il nuovo oggetto String.

La soluzione a questo problema è semplice. Se Label non è impostato su un valore ContentTemplate personalizzato, sostituire Label con un oggetto TextBlock ed eseguire l'associazione dati della proprietà Text alla stringa di origine.

Proprietà associata a dati

Durata dell'aggiornamento (ms)

Label.Content

835

TextBlock.Text

242

L'oggetto Hyperlink è un elemento del contenuto del flusso di livello inline che consente di ospitare collegamenti ipertestuali all'interno del contenuto del flusso.

Combinare collegamenti ipertestuali in un oggetto TextBlock

È possibile ottimizzare l'utilizzo di più elementi Hyperlink ragruppandoli insieme all'interno allo stesso oggetto TextBlock. In questo modo è possibile ridurre al minimo il numero di oggetti creati nell'applicazione. Ad esempio, può essere necessario visualizzare più collegamenti ipertestuali, come quelli riportati di seguito:

Home page MSN | MSN

Nell'esempio di markup riportato di seguito vengono illustrati più elementi TextBlock utilizzati per visualizzare i collegamenti ipertestuali:

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

Nell'esempio di markup riportato di seguito viene illustrato un modo più efficiente per visualizzare i collegamenti ipertestuali, utilizzando un solo oggetto 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>

Visualizzazione delle sottolineature nei collegamenti ipertestuali solo in caso di eventi MouseEnter

TextDecoration è un ornamento visivo che è possibile aggiungere al testo. Tuttavia, la creazione di un'istanza per tale oggetto può essere impegnativa in termini di prestazioni. Nel caso di un utilizzo esteso di elementi Hyperlink, si consideri la possibilità di visualizzare una sottolineatura solo al momento della generazione di un evento, ad esempio MouseEnter. Per ulteriori informazioni, vedere Procedura: utilizzare una decorazione di testo con un collegamento ipertestuale.

Visualizzazione dei collegamenti ipertestuali nel caso di evento MouseEnter

Collegamenti ipertestuali con TextDecoration

Nell'esempio di markup riportato di seguito viene illustrato un oggetto Hyperlink definito con e senza sottolineatura:

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

Nella tabella riportata di seguito viene illustrato il costo in termini di prestazioni per la visualizzazione di 1000 elementi Hyperlink con o senza sottolineatura.

Hyperlink

Durata della creazione (ms)

Durata del rendering (ms)

Con sottolineatura

289

1130

Senza sottolineatura

299

776

Funzionalità di formattazione del testo

WPF fornisce servizi di formato RTF, ad esempio le sillabazioni automatiche. Questi servizi possono influire sulle prestazioni dell'applicazione e devono essere utilizzati solo nei casi in cui è necessario.

Evitare l'utilizzo non necessario della sillabazione

Con la sillabazione automatica vengono ricercati i punti di interruzione per le righe di testo ed è possibile aggiungere posizioni di interruzione supplementari per le righe negli oggetti TextBlock e FlowDocument. Per impostazione predefinita, la funzionalità di sillabazione automatica è disabilitata in questi oggetti. È possibile abilitare questa funzionalità impostando la proprietà IsHyphenationEnabled dell'oggetto su true. Tuttavia, con l'abilitazione di questa funzionalità in WPF viene avviata l'interoperabilità Component Object Model (COM), operazione che può influire sulle prestazioni dell'applicazione. Si consiglia di utilizzare la sillabazione automatica solo quando è necessario.

Utilizzare con attenzione gli elementi Figure

Un elemento Figure rappresenta una parte di contenuto dinamico che può essere posizionata in modo assoluto all'interno di una pagina di contenuto. In alcuni casi, un oggetto Figure può determinare la riformattazione automatica di una pagina intera, se la posizione è in conflitto con il contenuto che è già stato disposto. È possibile ridurre al minimo la possibilità di una riformattazione non necessaria raggruppando gli elementi Figure l'uno accanto all'altro oppure dichiarandoli accanto all'inizio del contenuto in uno scenario con dimensione pagina fissa.

Paragrafo ottimale

La funzionalità di paragrafo ottimale dell'oggetto FlowDocument consente di disporre i paragrafi in modo che gli spazi vuoti vengano distribuiti nel modo più uniforme possibile. Per impostazione predefinita, la funzionalità di paragrafo ottimale è disabilitata. È possibile abilitare questa funzionalità impostando la proprietà IsOptimalParagraphEnabled dell'oggetto su true. Tuttavia, l'abilitazione di questa funzionalità avrà un impatto sulle prestazioni dell'applicazione. Si consiglia di non utilizzare la funzionalità di paragrafo ottimale a meno che non sia necessario.

Vedere anche

Concetti

Ottimizzazione delle prestazioni di applicazioni WPF

Pianificazione delle prestazioni dell'applicazione

Ottimizzazione delle prestazioni: sfruttare appieno l'hardware

Ottimizzazione delle prestazioni: layout e progettazione

Ottimizzazione delle prestazioni: grafica bidimensionale e creazione di immagini

Ottimizzazione delle prestazioni: comportamento degli oggetti

Ottimizzazione delle prestazioni: risorse di applicazioni

Ottimizzazione delle prestazioni: associazione dati

Ottimizzazione delle prestazioni: altri suggerimenti