Bagikan melalui


Mengoptimalkan Performa: Teks

WPF mencakup dukungan untuk presentasi konten teks melalui penggunaan kontrol antarmuka pengguna (UI) kaya fitur. Secara umum Anda dapat membagi penyajian teks dalam tiga lapisan:

  1. Glyphs Menggunakan objek dan GlyphRun secara langsung.

  2. FormattedText Menggunakan objek .

  3. Menggunakan kontrol tingkat tinggi, seperti TextBlock objek dan FlowDocument .

Topik ini menyediakan rekomendasi performa penyajian teks.

Penyajian Teks di Tingkat Glyph

Windows Presentation Foundation (WPF) menyediakan dukungan teks tingkat lanjut termasuk markup tingkat glyph dengan akses langsung ke Glyphs untuk pelanggan yang ingin mencegat dan mempertahankan teks setelah pemformatan. Fitur-fitur ini memberikan dukungan penting untuk berbagai persyaratan penyajian teks dalam setiap skenario berikut.

  • Tampilan layar dokumen berformat tetap.

  • Skenario cetak.

    • Extensible Application Markup Language (XAML) sebagai bahasa printer perangkat.

    • Microsoft XPS Document Writer.

    • Driver printer sebelumnya, output dari aplikasi Win32 ke format tetap.

    • Format spool cetak.

  • Representasi dokumen berformat tetap, termasuk klien untuk versi Windows sebelumnya dan perangkat komputasi lainnya.

Catatan

Glyphs dan GlyphRun dirancang untuk presentasi dokumen format tetap dan skenario cetak. WPF menyediakan beberapa elemen untuk skenario tata letak umum dan antarmuka pengguna (UI) seperti Label dan TextBlock. Untuk informasi selengkapnya tentang tata letak dan skenario UI, lihat Tipografi di WPF.

Contoh berikut menunjukkan cara menentukan properti untuk Glyphs objek di XAML. Contoh mengasumsikan bahwa font Arial, Courier New, dan Times New Roman diinstal di folder C:\WINDOWS\Fonts di komputer lokal.

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

Menggunakan DrawglyphRun

Jika Anda memiliki kontrol kustom dan ingin merender glyph, gunakan metode .DrawGlyphRun

WPF juga menyediakan layanan tingkat bawah untuk pemformatan teks kustom melalui penggunaan FormattedText objek. Cara penyajian teks yang paling efisien di Windows Presentation Foundation (WPF) adalah dengan menghasilkan konten teks pada tingkat glyph menggunakan Glyphs dan GlyphRun. Namun, biaya efisiensi ini adalah hilangnya pemformatan teks kaya yang mudah digunakan, yang merupakan fitur bawaan kontrol Windows Presentation Foundation (WPF), seperti TextBlock dan FlowDocument.

Objek FormattedText

Objek FormattedText memungkinkan Anda menggambar teks multibaris, di mana setiap karakter dalam teks dapat diformat satu per satu. Untuk informasi selengkapnya, lihat Menggambar Teks Berformat.

Untuk membuat teks berformat, panggil FormattedText konstruktor untuk membuat FormattedText objek. Setelah Anda membuat string teks berformat awal, Anda bisa menerapkan rentang gaya pemformatan. Jika aplikasi Anda ingin menerapkan tata letaknya sendiri, maka FormattedText objek adalah pilihan yang lebih baik daripada menggunakan kontrol, seperti TextBlock. Untuk informasi selengkapnya tentang FormattedText objek, lihat Menggambar Teks Berformat .

Objek menyediakan FormattedText kemampuan pemformatan teks tingkat rendah. Anda bisa menerapkan beberapa gaya pemformatan ke satu atau beberapa karakter. Misalnya, Anda dapat memanggil SetFontSize metode dan SetForegroundBrush untuk mengubah pemformatan lima karakter pertama dalam teks.

Contoh kode berikut membuat FormattedText objek dan merendernya.

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

Kontrol FlowDocument, TextBlock, dan Label

WPF menyertakan beberapa kontrol untuk menggambar teks ke layar. Setiap kontrol ditargetkan ke skenario yang berbeda dan memiliki daftar fitur dan batasannya sendiri.

FlowDocument Berdampak pada Performa Lebih dari TextBlock atau Label

Secara umum, TextBlock elemen harus digunakan ketika dukungan teks terbatas diperlukan, seperti kalimat singkat dalam antarmuka pengguna (UI). Label dapat digunakan ketika dukungan teks minimal diperlukan. Elemen FlowDocument ini adalah kontainer untuk dokumen yang dapat dialirkan kembali yang mendukung presentasi konten yang kaya, dan oleh karena itu, memiliki dampak performa yang lebih besar daripada menggunakan TextBlock kontrol atau Label .

Untuk informasi selengkapnya tentang FlowDocument, lihat Gambaran Umum Dokumen Alur.

Hindari Menggunakan TextBlock di FlowDocument

Elemen TextBlock ini berasal dari UIElement. Elemen Run ini berasal dari TextElement, yang lebih murah untuk digunakan daripada UIElementobjek -turunan. Jika memungkinkan, gunakan Run daripada TextBlock menampilkan konten teks dalam FlowDocument.

Sampel markup berikut mengilustrasikan dua cara mengatur konten teks dalam 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>

Hindari Menggunakan Jalankan untuk Mengatur Properti Teks

Secara umum, menggunakan Run dalam TextBlock lebih intensif performa daripada tidak menggunakan objek eksplisit Run sama sekali. Jika Anda menggunakan Run untuk mengatur properti teks, atur properti tersebut langsung di sebagai gantinya TextBlock .

Sampel markup berikut mengilustrasikan dua cara ini untuk mengatur properti teks, dalam hal ini, FontWeight properti :

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

Tabel berikut menunjukkan biaya menampilkan 1000 TextBlock objek dengan dan tanpa eksplisit Run.

Jenis TextBlock Waktu pembuatan (ms) Waktu render (ms)
Menjalankan properti teks pengaturan 146 540
Properti teks pengaturan TextBlock 43 453

Hindari Pengikatan Data ke Properti Label.Content

Bayangkan skenario di mana Anda memiliki Label objek yang sering diperbarui dari String sumber. Saat data yang mengikat Label properti elemen Content ke String objek sumber, Anda mungkin mengalami performa yang buruk. Setiap kali sumber String diperbarui, objek lama String dibuang dan baru String dibuat ulang—karena String objek tidak dapat diubah, objek tidak dapat diubah. Ini, pada gilirannya, menyebabkan ContentPresenterLabel objek membuang konten lamanya dan meregenerasi konten baru untuk menampilkan konten baru String.

Solusi untuk masalah ini sederhana. Label Jika tidak diatur ke nilai kustomContentTemplate, ganti Label dengan TextBlock data dan ikat propertinya Text ke string sumber.

Properti terikat data Waktu pembaruan (ms)
Label.Content 835
TextBlock.Text 242

Objek Hyperlink adalah elemen konten alur tingkat sebaris yang memungkinkan Anda menghosting hyperlink dalam konten alur.

Anda dapat mengoptimalkan penggunaan beberapa Hyperlink elemen dengan mengelompokkannya bersama-sama dalam TextBlock. Ini membantu meminimalkan jumlah objek yang Anda buat di aplikasi Anda. Misalnya, Anda mungkin ingin menampilkan beberapa hyperlink, seperti berikut ini:

Beranda MSN | MSN saya

Contoh markup berikut menunjukkan beberapa TextBlock elemen yang digunakan untuk menampilkan hyperlink:

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

Contoh markup berikut menunjukkan cara yang lebih efisien untuk menampilkan hyperlink, kali ini, menggunakan satu 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>

Objek TextDecoration adalah ornamentasi visual yang dapat Anda tambahkan ke teks; namun, itu bisa menjadi performa intensif untuk membuat instans. Jika Anda menggunakan elemen secara Hyperlink ekstensif, pertimbangkan untuk menampilkan garis bawah hanya saat memicu peristiwa, seperti MouseEnter peristiwa. Untuk informasi selengkapnya, lihat Menentukan Apakah Hyperlink digaris bawahi.

Gambar berikut menunjukkan bagaimana peristiwa MouseEnter memicu hyperlink bergaris bawah:

Hyperlinks displaying TextDecorations

Sampel markup berikut menunjukkan yang Hyperlink ditentukan dengan dan tanpa garis bawah:

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

Tabel berikut menunjukkan biaya performa menampilkan 1000 Hyperlink elemen dengan dan tanpa garis bawah.

Hyperlink Waktu pembuatan (ms) Waktu render (ms)
Dengan garis bawah 289 1130
Tanpa garis bawah 299 776

Fitur Pemformatan Teks

WPF menyediakan layanan pemformatan teks yang kaya, seperti tanda hubung otomatis. Layanan ini dapat memengaruhi performa aplikasi dan hanya boleh digunakan saat diperlukan.

Hindari Penggunaan Tanda Hubung yang Tidak Perlu

Tanda hubung otomatis menemukan titik henti tanda hubung untuk baris teks, dan memungkinkan posisi pemisah tambahan untuk baris dalam TextBlock dan FlowDocument objek. Secara default, fitur tanda hubung otomatis dinonaktifkan dalam objek ini. Anda dapat mengaktifkan fitur ini dengan mengatur properti IsHyphenationEnabled objek ke true. Namun, mengaktifkan fitur ini menyebabkan WPF memulai interoperabilitas Model Objek Komponen (COM), yang dapat memengaruhi performa aplikasi. Disarankan agar Anda tidak menggunakan tanda hubung otomatis kecuali Anda membutuhkannya.

Gunakan Gambar Dengan Hati-hati

Figure Elemen mewakili sebagian konten alur yang dapat benar-benar diposisikan dalam halaman konten. Dalam beberapa kasus, Figure dapat menyebabkan seluruh halaman diformat ulang secara otomatis jika posisinya bertabrakan dengan konten yang telah ditata. Anda dapat meminimalkan kemungkinan pemformatan ulang yang tidak perlu dengan mengelompokkan Figure elemen di samping satu sama lain, atau mendeklarasikannya di dekat bagian atas konten dalam skenario ukuran halaman tetap.

Paragraf Optimal

Fitur paragraf optimal dari FlowDocument objek menjabarkan paragraf sehingga spasi kosong didistribusikan secara merata. Secara default, fitur paragraf optimal dinonaktifkan. Anda dapat mengaktifkan fitur ini dengan mengatur properti objek IsOptimalParagraphEnabled ke true. Namun, mengaktifkan fitur ini berdampak pada performa aplikasi. Disarankan agar Anda tidak menggunakan fitur paragraf optimal kecuali Anda membutuhkannya.

Baca juga