Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
WPF включает поддержку представления текстового содержимого с помощью элементов управления пользовательским интерфейсом с расширенными возможностями. Как правило, можно разделить отрисовку текста на три уровня:
FormattedText Использование объекта.
Использование высокоуровневых элементов управления, таких как TextBlock и FlowDocument объекты.
В этом разделе приведены рекомендации по производительности отрисовки текста.
Визуализация текста на уровне глифа
Windows Presentation Foundation (WPF) обеспечивает расширенную поддержку текста, включая разметку уровня глифа с прямым доступом к Glyphs, для клиентов, которые хотят перехватывать и сохранять текст после форматирования. Эти функции обеспечивают критичную поддержку различных требований к отрисовке текста в каждом из следующих сценариев.
Экран отображения документов фиксированного формата.
Сценарии для печати.
Расширяемый язык разметки приложений (XAML) в качестве языка принтера устройства.
Модуль записи документов Microsoft XPS.
Предыдущие драйверы принтера преобразовывали выходные данные из приложений Win32 в фиксированный формат.
Формат спула печати.
Представление документа фиксированного формата, включая клиенты для предыдущих версий Windows и других вычислительных устройств.
Замечание
Glyphs и GlyphRun предназначены для сценариев представления документов фиксированного формата и печати. WPF предоставляет несколько элементов для общих сценариев макета и пользовательского интерфейса, таких как Label и TextBlock. Дополнительные сведения о сценариях макета и пользовательского интерфейса см. в разделе "Типография" в WPF.
В следующих примерах показано, как определить свойства для объекта Glyphs в XAML. В примерах предполагается, что шрифты Arial, Courier New и Times New Roman устанавливаются в папку C:\WINDOWS\Fonts на локальном компьютере.
<!-- 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>
Использование DrawGlyphRun
Если у вас есть настраиваемый элемент управления и вы хотите отобразить глифы, используйте метод DrawGlyphRun.
WPF также предоставляет службы нижнего уровня для пользовательского форматирования текста с помощью объекта FormattedText. Наиболее эффективным способом отрисовки текста в Windows Presentation Foundation (WPF) является создание текстового содержимого на уровне глифа с помощью Glyphs и GlyphRun. Однако стоимость этой эффективности приводит к потере простого использования форматирования текста, которые являются встроенными функциями элементов управления Windows Presentation Foundation (WPF), например TextBlock и FlowDocument.
Объект "FormattedText"
Объект FormattedText позволяет нарисовать многострочный текст, в котором каждый символ в тексте может быть отформатирован по отдельности. Дополнительные сведения см. в разделе "Форматированный текст документа".
Чтобы создать форматированный текст, вызовите FormattedText конструктор для создания FormattedText объекта. После создания исходной текстовой строки форматирования можно применить диапазон стилей форматирования. Если вашему приложению нужно реализовать свой собственный макет, то объект FormattedText лучше подходит, чем использование элемента управления, такого как TextBlock. Дополнительные сведения об объекте FormattedText см. в разделе "Форматированный текст документа ".
Объект FormattedText предоставляет низкоуровневую возможность форматирования текста. К одному или нескольким символам можно применить несколько стилей форматирования. Например, можно вызвать и SetFontSizeSetForegroundBrush методы, чтобы изменить форматирование первых пяти символов в тексте.
Следующий пример кода создает FormattedText объект и отрисовывает его.
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 и Label
WPF включает несколько элементов управления для рисования текста на экране. Каждый элемент управления предназначен для другого сценария и имеет собственный список функций и ограничений.
FlowDocument влияет на производительность больше, чем TextBlock или Label
Как правило, элемент TextBlock следует использовать, если требуется ограниченная поддержка текста, например краткое предложение в пользовательском интерфейсе. Label можно использовать, если требуется минимальная поддержка текста. Элемент FlowDocument — это контейнер для документов с возможностью изменения потоков текста, которые поддерживают богатое представление содержимого и, следовательно, оказывают большее влияние на производительность, чем использование управляющих элементов TextBlock или Label.
Дополнительные сведения см. в разделе "Общие сведения о FlowDocumentдокументе потока".
Избегайте использования TextBlock в FlowDocument
Элемент TextBlock является производным от UIElement. Элемент Run является производным от TextElementэлемента, который является менее дорогостоящим для использования, чем производный UIElementобъект. По возможности используйте Run, а не TextBlock, для отображения текстового содержимого в FlowDocument.
В следующем примере разметки показаны два способа задать текстовое содержимое внутри 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>
Избегайте использования запуска для задания свойств текста
Как правило, использование Run внутри TextBlock более ресурсоемко, чем полное отсутствие явного объекта Run. Если вы используете Run для задания текстовых свойств, вместо этого задайте эти свойства непосредственно на TextBlock.
В следующем примере разметки показаны два способа настройки текстового свойства в данном случае 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>
В следующей таблице показана стоимость отображения 1000 TextBlock объектов с явным Run и без явного Run.
Тип TextBlock | Время создания (мс) | Время отрисовки (мс) |
---|---|---|
Выполнение настройки текстовых свойств | 146 | 540 |
Установка текстовых свойств для TextBlock | 43 | 453 |
Избегайте привязки данных к свойству Label.Content
Представьте сценарий, в котором у вас есть Label объект, который часто обновляется из String источника. При привязке свойства элемента Label к исходному объекту Content может возникнуть падение производительности. При каждом обновлении источника String старый String объект удаляется и создается новый String объект, так как String объект неизменяем, его нельзя изменить. Это, в свою очередь, приводит к тому, что ContentPresenter объекта Label удаляет свое старое содержимое и заново создает новое содержимое для отображения нового String.
Решение этой проблемы просто. Если Label не задано для пользовательского ContentTemplate значения, замените Label на TextBlock и привяжите его свойство Text к исходной строке.
Свойство привязки данных | Время обновления (мс) |
---|---|
Метка.Содержимое | 835 |
TextBlock.Text | 242 |
Гиперссылка
Объект Hyperlink — это встроенный элемент содержимого потока, который позволяет размещать гиперссылки в содержимом потока.
Объединение гиперссылок в одном объекте TextBlock
Вы можете оптимизировать использование нескольких Hyperlink элементов, группируя их вместе в одном и том же TextBlock. Это помогает свести к минимуму количество объектов, создаваемых в приложении. Например, может потребоваться отобразить несколько гиперссылок, например следующие:
MSN Home | Моя MSN
В следующем примере разметки показаны несколько TextBlock элементов, используемых для отображения гиперссылок:
<!-- 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>
В следующем примере разметки показан более эффективный способ отображения гиперссылок, на этот раз с помощью одного 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>
Отображение подчеркивания гиперссылки только на события MouseEnter
Объект TextDecoration — это визуальное украшение, которое можно добавить в текст; однако при создании экземпляра оно может потреблять много ресурсов. Если вы активно используете элементы Hyperlink, рассмотрите вариант отображения подчеркивания только при активации события, например, события MouseEnter. Дополнительные сведения см. в разделе "Укажите, подчеркивается ли гиперссылка".
На следующем рисунке показано, как событие MouseEnter активирует подчеркнутую гиперссылку:
В следующем примере разметки показана Hyperlink, определенная с подчеркиванием и без нее:
<!-- 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>
В следующей таблице показаны затраты на производительность при отображении 1000 Hyperlink элементов с подчеркиванием и без него.
гиперссылка | Время создания (мс) | Время отрисовки (мс) |
---|---|---|
С подчеркиванием | 289 | 1130 |
Без подчеркивания | 299 | 776 |
Функции форматирования текста
WPF предоставляет службы форматирования форматированного текста, такие как автоматические дефисы. Эти службы могут повлиять на производительность приложений и должны использоваться только при необходимости.
Избегайте ненужного использования дефиса
Автоматическая дефисация находит точки останова дефиса для строк текста и позволяет использовать дополнительные позиции останова для строк и TextBlockFlowDocument объектов. По умолчанию функция автоматической дефисации отключена в этих объектах. Эту функцию можно включить, установив для свойства IsHyphenationEnabled значение true
. Однако включение этой функции приводит к тому, что WPF инициирует взаимодействие с объектной моделью компонентов (COM), что может повлиять на производительность приложения. Рекомендуется не использовать автоматическое дефисирование, если это не требуется.
Тщательно используйте цифры
Элемент Figure представляет собой элемент потока, который может быть абсолютно позиционирован на странице содержимого. В некоторых случаях может Figure привести к автоматической переформатации всей страницы, если ее положение сталкивается с содержимым, которое уже было выложено. Можно свести к минимуму возможность ненужного переформатирования, группируя Figure элементы рядом друг с другом или объявляя их в верхней части содержимого в сценарии фиксированного размера страницы.
Оптимальный абзац
Оптимальная функция абзаца FlowDocument объекта выделяет абзацы таким образом, чтобы пробелы распределялись как можно более равномерно. По умолчанию функция оптимального абзаца отключена. Эту функцию можно включить, задав для свойства объекта IsOptimalParagraphEnabled значение true
. Однако включение этой функции влияет на производительность приложения. Рекомендуется не использовать оптимальную функцию абзаца, если она не нужна.
См. также
.NET Desktop feedback