Оптимизация производительности: Текста
WPF включает поддержку представления текстового контента с помощью многофункциональных UI элементов управления. В целом можно разделить отрисовку текста на три уровня.
С помощью FormattedText объекта.
Использование высокоуровневых элементов управления, таких как TextBlock и FlowDocument объектов.
В этом разделе даются рекомендации по повышению производительности отрисовки текста.
Отрисовка текста на уровне глифа
Windows Presentation Foundation (WPF) обеспечивает расширенную поддержку текста включая разметку на уровне глифа с прямым доступом к Glyphs для клиентов, которым требуется перехватывать и сохранять текст после форматирования. Эти функции обеспечивают критически важную поддержку различных требований к отрисовке текста в каждом из следующих сценариев.
Отображение на экране документов фиксированного формата.
Сценарии печати.
XAML как язык принтера.
Средство записи XPS-документов (Майкрософт).
Предыдущие драйверы принтера, вывод из приложений Win32 в фиксированный формат.
Формат очереди печати.
Представление документов фиксированного формата, включая клиенты предыдущих версий Windows и другие вычислительные устройства.
Note
Glyphs и GlyphRun предназначены для представления документов фиксированного формата и сценариев печати. Windows Presentation Foundation (WPF) предоставляет несколько элементов для общего макета и UI сценариях, например Label и TextBlock. Дополнительные сведения о макете и сценариях UI см. в статье Оформление в WPF.
Следующие примеры показывают, как следует указывать свойства для Glyphs объекта в XAML. Glyphs Представляет выходные данные GlyphRun в 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. Однако ценой этой эффективности будет потеря прост в использовании форматирования RTF, которые являются встроенными функциями из Windows Presentation Foundation (WPF) элементы управления, такие как TextBlock и FlowDocument.
Объект FormattedText
FormattedText Объект позволяет рисовать многострочный текст, в котором каждый символ в текст можно форматировать по отдельности. Дополнительные сведения см. в разделе Рисование форматированного текста.
Чтобы создать форматированный текст, вызовите FormattedText конструктор для создания FormattedText объекта. После создания исходной строки форматированного текста можно применить ряд стилей форматирования. Если в приложении требуется реализовать собственный макет, а затем FormattedText объект является более предпочтительной, чем использование элемента управления, такие как TextBlock. Дополнительные сведения о FormattedText объекта, см. в разделе Рисование форматированного текста .
FormattedText Предоставляет возможность низкоуровневого форматирования текста. К одному или более символам можно применить несколько стилей форматирования. Например, можно вызвать оба SetFontSize и SetForegroundBrush методы для изменения форматирования первые пять символов в тексте.
В следующем примере кода создается 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));
}
Элементы управления FlowDocument, TextBlock и Label
WPF содержит несколько элементов управления для рисования текста на экране. Каждый элемент управления предназначен для своего сценария и имеет собственный список функций и ограничений.
FlowDocument влияет на производительность больше, чем TextBlock и Label
В общем случае TextBlock элемент должен использоваться при необходимости, например короткого предложения в ограниченная поддержка текста UI . 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 для задания свойств текста
В целом, использование 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.
Тип TextBlock | Время создания (мс) | Время отрисовки (мс) |
---|---|---|
Установка свойств текста с помощью Run | 146 | 540 |
Установка свойств текста с помощью TextBlock | 43 | 453 |
Избегайте привязки данных к свойству Label.Content
Представьте себе ситуацию, где у вас есть Label объект, который постоянно обновляется из String источника. При привязке данных Label элемента Content свойства String исходный объект, может наблюдаться низкая производительность. Каждый раз, когда источник String обновляется, старый String объект удаляется, а новый String создается заново, поскольку String является неизменяемым, его невозможно изменить. Это, в свою очередь, вызовет переход ContentPresenter из Label объект, который удаляет свое устаревшее содержимое и создает новое содержимое для отображения новых String.
Решение этой проблемы довольно простое. Если Label не установлено пользовательское ContentTemplate значение, замените Label с TextBlock и выполнить привязку данных его Text значение исходной строки.
Свойство с привязкой данных | Время обновления (мс) |
---|---|
Label.Content | 835 |
TextBlock.Text | 242 |
Гиперссылка
Hyperlink Объект — это элемент содержимого потока встроенного уровня, позволяющим размещать гиперссылки в содержимом потока.
Объединение гиперссылок в одном объекте TextBlock
Вы можете оптимизировать использование нескольких Hyperlink элементов, объединив их в одном TextBlock. Это позволяет минимизировать число объектов, создаваемых в приложении. Например, может потребоваться отобразить несколько гиперссылок, как показано ниже.
Домашняя страница MSN | Мой 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 предоставляет службы, такие как автоматическая расстановка переносов форматирования RTF. Эти службы могут влиять на производительность приложения и должны использоваться только при необходимости.
Избегайте излишнего использования расстановки переносов
Автоматическая расстановка переносов находит точки останова дефиса для строк текста и разрешает дополнительные позиции разрыва для строк в TextBlock и FlowDocument объектов. По умолчанию возможность автоматического переноса в этих объектах отключена. Эту функцию можно включить, установив свойство IsHyphenationEnabled объекта в значение true
. Однако включение этой функции заставляет WPF инициировать взаимодействие Модель COM, которое может повлиять на производительность приложения. Рекомендуется не использовать автоматическую расстановку переносов, если это не является обязательным.
Внимательно используйте рисунки
Объект Figure элемент представляет часть неформатированного содержимого, которое может быть абсолютно позиционировано внутри страницы содержимого. В некоторых случаях Figure может привести к целой страницы автоматическое переформатирование, если ее положение конфликтует с уже размещенным содержимым. Можно свести к минимуму вероятность ненужного переформатирования либо путем группировки Figure элементов друг с другом, либо объявить их в верхней части содержимого в сценарии фиксированного размера страницы.
Оптимальный абзац
Средство оптимального абзаца из FlowDocument размещает абзацы, чтобы пустое пространство распределялось максимально равномерно. По умолчанию средство оптимального абзаца отключено. Вы можете включить эту функцию, задав объекта IsOptimalParagraphEnabled свойства true
. Однако включение этой функции влияет на производительность приложения. Рекомендуется не использовать средство оптимального абзаца без необходимости.