Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Windows Presentation Foundation (WPF) предоставляет надежный набор API для включения текста в приложение. API макета и пользовательского интерфейса, например TextBlock, предоставляют наиболее распространенные и общие элементы для представления текста. API рисования, такие как GlyphRunDrawing и FormattedText, предоставляют средства для включения форматированного текста в рисунки. На самом расширенном уровне WPF предоставляет расширяемый механизм форматирования текста для управления каждым аспектом представления текста, такими как управление текстовым хранилищем, управление форматированием текста и управление внедренными объектами.
В этом разделе приведены общие сведения о форматировании текста WPF. В нем основное внимание уделяется реализации клиента и использованию обработчика форматирования текста WPF.
Замечание
Все примеры кода в этом документе можно найти в примере расширенного форматирования текста.
Предпосылки
В этом разделе предполагается, что вы знакомы с API более высокого уровня, используемыми для текстовой презентации. Большинству пользовательских сценариев не требуется расширенные API форматирования текста, рассмотренные в этом разделе. Для ознакомления с различными текстовыми API см. в документах в WPF.
Расширенное форматирование текста
Элементы управления текстовым макетом и пользовательским интерфейсом в WPF предоставляют свойства форматирования, которые позволяют легко включать форматированный текст в приложение. Эти элементы управления предоставляют ряд свойств для обработки представления текста, включающего его шрифт, размер и цвет. В обычных условиях эти элементы управления могут обрабатывать большинство текстовых презентаций в приложении. Однако для некоторых сложных сценариев требуется управление текстовым хранилищем, а также представление текста. WPF предоставляет расширяемый механизм форматирования текста для этой цели.
Расширенные функции форматирования текста, найденные в WPF, состоят из обработчика форматирования текста, текстового хранилища, выполнения текста и свойств форматирования. Модуль форматирования текста, TextFormatter, создает строки текста, которые будут использоваться для презентации. Это достигается началом процесса форматирования строк и вызовом FormatLineформатировщика текста. Модуль форматирования текста извлекает фрагменты текста из текстового хранилища, вызывая метод GetTextRun хранилища. Затем объекты TextRun формируются в TextLine объекты текстовым форматировщиком и передаются приложению для проверки или отображения.
Использование средства форматирования текста
TextFormatter является движком форматирования текста WPF и предоставляет услуги для форматирования и разбиения текстовых строк. Модуль форматирования текста может обрабатывать различные текстовые форматы и стили абзацев, а также поддерживать международный текстовый макет.
В отличие от традиционного API текста, TextFormatter взаимодействует с клиентом макета текста с помощью набора методов обратного вызова. Клиенту требуется предоставить эти методы в реализации класса TextSource. На следующей схеме показано взаимодействие текстового макета между клиентским приложением и TextFormatter.
TextFormatter
Модуль форматирования текста используется для получения форматированных текстовых строк из текстового хранилища, который является реализацией TextSource. Это делается путем создания экземпляра форматировщика текста с помощью метода Create. Этот метод создает экземпляр текстового форматирования и задает максимальное значение высоты и ширины строки. После создания экземпляра форматировщика текста процесс создания строки запускается путем вызова метода FormatLine. TextFormatter обращается к источнику текста, чтобы получить параметры текста и форматирования для фрагментов текста, составляющих строку.
В следующем примере показан процесс форматирования текстового хранилища. Объект TextFormatter используется для извлечения текстовых строк из текстового хранилища, а затем форматирования текстовой строки для рисования в DrawingContext.
// Create a DrawingGroup object for storing formatted text.
textDest = new DrawingGroup();
DrawingContext dc = textDest.Open();
// Update the text store.
_textStore.Text = textToFormat.Text;
_textStore.FontRendering = _currentRendering;
// Create a TextFormatter object.
TextFormatter formatter = TextFormatter.Create();
// Format each line of text from the text store and draw it.
while (textStorePosition < _textStore.Text.Length)
{
// Create a textline from the text store using the TextFormatter object.
using (TextLine myTextLine = formatter.FormatLine(
_textStore,
textStorePosition,
96*6,
new GenericTextParagraphProperties(_currentRendering),
null))
{
// Draw the formatted text into the drawing context.
myTextLine.Draw(dc, linePosition, InvertAxes.None);
// Update the index position in the text store.
textStorePosition += myTextLine.Length;
// Update the line position coordinate for the displayed line.
linePosition.Y += myTextLine.Height;
}
}
// Persist the drawn text content.
dc.Close();
// Display the formatted text in the DrawingGroup object.
myDrawingBrush.Drawing = textDest;
' Create a DrawingGroup object for storing formatted text.
textDest = New DrawingGroup()
Dim dc As DrawingContext = textDest.Open()
' Update the text store.
_textStore.Text = textToFormat.Text
_textStore.FontRendering = _currentRendering
' Create a TextFormatter object.
Dim formatter As TextFormatter = TextFormatter.Create()
' Format each line of text from the text store and draw it.
Do While textStorePosition < _textStore.Text.Length
' Create a textline from the text store using the TextFormatter object.
Using myTextLine As TextLine = formatter.FormatLine(_textStore, textStorePosition, 96*6, New GenericTextParagraphProperties(_currentRendering), Nothing)
' Draw the formatted text into the drawing context.
myTextLine.Draw(dc, linePosition, InvertAxes.None)
' Update the index position in the text store.
textStorePosition += myTextLine.Length
' Update the line position coordinate for the displayed line.
linePosition.Y += myTextLine.Height
End Using
Loop
' Persist the drawn text content.
dc.Close()
' Display the formatted text in the DrawingGroup object.
myDrawingBrush.Drawing = textDest
Реализация клиентского текстового хранилища
При расширении обработчика форматирования текста необходимо реализовать все аспекты текстового хранилища и управлять ими. Это не тривиальная задача. Текстовое хранилище отвечает за отслеживание свойств выполнения текста, свойств абзаца, внедренных объектов и другого аналогичного содержимого. Он также предоставляет форматировщику текста отдельные объекты TextRun, которые используются для создания объектов TextLine.
Чтобы обработать виртуализацию текстового хранилища, текстовое хранилище должно быть производным от TextSource. TextSource определяет метод, с помощью которого средство форматирования текста извлекает фрагменты текста из текстового хранилища. GetTextRun — это метод, который используется текстовым форматировщиком для извлечения текстовых сегментов, которые применяются при форматировании строк. Вызов GetTextRun повторяется текстовым форматировщиком до тех пор, пока не возникнет одно из следующих условий:
Возвращается TextEndOfLine или подкласс.
Совокупная ширина фрагментов текста превышает максимальную ширину строки, указанную в вызове для создания форматировщика текста или вызова метода FormatLine форматировщика текста.
Возвращается новая последовательность Юникода, например CF, LF или CRLF.
Предоставление текстовых последовательностей
Основой процесса форматирования текста является взаимодействие между текстовым форматировщиком и текстовым хранилищем. Ваша реализация TextSource предоставляет форматировщику текста объекты TextRun и свойства, которые используются для форматирования текстовых интервалов. Это взаимодействие обрабатывается методом GetTextRun, который вызывается текстовым форматировщиком.
В следующей таблице показаны некоторые предопределенные объекты TextRun.
Тип TextRun | Использование |
---|---|
TextCharacters | Специализированный текстовый блок, используемый для передачи представления символьных глифов обратно в средство форматирования текста. |
TextEmbeddedObject | Специализированный текстовый элемент, используемый для предоставления содержимого, в котором измерение, определение попаданий и рисование выполняются целиком, например, кнопка или изображение, в тексте. |
TextEndOfLine | Специальный текстовый блок, используемый для обозначения конца строки. |
TextEndOfParagraph | Специализированный фрагмент текста, используемый для обозначения конца абзаца. |
TextEndOfSegment | Специализированный текстовый блок, используемый для обозначения конца сегмента, например, для завершения области, затронутой предыдущим TextModifier. |
TextHidden | Специализированный текстовый блок, используемый для обозначения диапазона скрытых символов. |
TextModifier | Специализированный текстовый участок, используемый для изменения свойств текстовых участков в своей области действия. Область расширяется до следующего соответствующего текстового блока TextEndOfSegment или до следующего TextEndOfParagraph. |
Любой предопределенный TextRun объекты можно подклассировать. Это позволяет источнику текста предоставлять форматировщику текстовые сегменты, включающие пользовательские данные.
В следующем примере показан метод GetTextRun. Это хранилище текстов возвращает TextRun объектов в форматировщик текста для обработки.
// Used by the TextFormatter object to retrieve a run of text from the text source.
public override TextRun GetTextRun(int textSourceCharacterIndex)
{
// Make sure text source index is in bounds.
if (textSourceCharacterIndex < 0)
throw new ArgumentOutOfRangeException("textSourceCharacterIndex", "Value must be greater than 0.");
if (textSourceCharacterIndex >= _text.Length)
{
return new TextEndOfParagraph(1);
}
// Create TextCharacters using the current font rendering properties.
if (textSourceCharacterIndex < _text.Length)
{
return new TextCharacters(
_text,
textSourceCharacterIndex,
_text.Length - textSourceCharacterIndex,
new GenericTextRunProperties(_currentRendering));
}
// Return an end-of-paragraph if no more text source.
return new TextEndOfParagraph(1);
}
' Used by the TextFormatter object to retrieve a run of text from the text source.
Public Overrides Function GetTextRun(ByVal textSourceCharacterIndex As Integer) As TextRun
' Make sure text source index is in bounds.
If textSourceCharacterIndex < 0 Then
Throw New ArgumentOutOfRangeException("textSourceCharacterIndex", "Value must be greater than 0.")
End If
If textSourceCharacterIndex >= _text.Length Then
Return New TextEndOfParagraph(1)
End If
' Create TextCharacters using the current font rendering properties.
If textSourceCharacterIndex < _text.Length Then
Return New TextCharacters(_text, textSourceCharacterIndex, _text.Length - textSourceCharacterIndex, New GenericTextRunProperties(_currentRendering))
End If
' Return an end-of-paragraph if no more text source.
Return New TextEndOfParagraph(1)
End Function
Замечание
В этом примере текстовое хранилище предоставляет одинаковые свойства текста для всего текста. Расширенные текстовые хранилища должны реализовать собственное управление диапазоном, чтобы отдельные символы имели разные свойства.
Указание свойств форматирования
TextRun объекты форматируются с помощью свойств, предоставляемых текстовым хранилищем. Эти свойства относятся к двум типам, TextParagraphProperties и TextRunProperties. TextParagraphProperties может обрабатывать свойства абзаца, включающие такие элементы как TextAlignment и FlowDirection. TextRunProperties — это свойства, которые могут отличаться для каждого текстового фрагмента в абзаце, например кисть переднего плана, Typefaceи размер шрифта. Чтобы реализовать пользовательские типы свойств для абзаца и текстового фрагмента, ваше приложение должно создавать классы, производные от TextParagraphProperties и TextRunProperties соответственно.
См. также
.NET Desktop feedback