Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Windows Presentation Foundation (WPF) fornece um conjunto robusto de APIs para incluir texto em seu aplicativo. As APIs de interface do usuário (interface do usuário) e layout, como TextBlock, fornecem os elementos mais comuns e de uso geral para apresentação de texto. As APIs de desenho, como GlyphRunDrawing e FormattedText, fornecem um meio para incluir texto formatado em desenhos. No nível mais avançado, o WPF fornece um mecanismo extensível de formatação de texto para controlar todos os aspectos da apresentação de texto, como gerenciamento de repositório de texto, gerenciamento de formatação de execução de texto e gerenciamento de objetos inseridos.
Este tópico fornece uma introdução à formatação de texto do WPF. Ele se concentra na implementação do cliente e no uso do mecanismo de formatação de texto do WPF.
Observação
Todos os exemplos de código neste documento podem ser encontrados no exemplo de formatação de texto avançado.
Pré-requisitos
Este tópico pressupõe que você esteja familiarizado com as APIs de nível superior usadas para apresentação de texto. A maioria dos cenários de usuário não exigirá as APIs avançadas de formatação de texto discutidas neste tópico. Para obter uma introdução às diferentes APIs de texto, consulte Documentos no WPF.
Formatação avançada de texto
O layout de texto e os controles de interface do usuário no WPF fornecem propriedades de formatação que permitem incluir facilmente texto formatado em seu aplicativo. Esses controles expõem várias propriedades para lidar com a apresentação de texto, incluindo sua fonte, tamanho e cor. Em circunstâncias comuns, esses controles podem lidar com a maioria da apresentação de texto em seu aplicativo. No entanto, alguns cenários avançados exigem o controle do armazenamento de texto, bem como a apresentação de texto. O WPF fornece um mecanismo de formatação de texto extensível para essa finalidade.
Os recursos avançados de formatação de texto encontrados no WPF consistem em um mecanismo de formatação de texto, um repositório de texto, execuções de texto e propriedades de formatação. O mecanismo TextFormatterde formatação de texto cria linhas de texto a serem usadas para apresentação. Isso é feito iniciando o processo de formatação de linha e chamando o formatador de texto.FormatLine O formatador de texto recupera segmentos de texto do seu repositório de texto ao chamar o método GetTextRun do repositório. Os objetos TextRun são então formados em objetos TextLine pelo formatador de texto e passados ao seu aplicativo para inspeção ou exibição.
Usando o Formatador de Texto
TextFormatter é o mecanismo de formatação de texto do WPF e fornece serviços para formatação e quebra de linhas de texto. O formatador de texto pode lidar com diferentes formatos de caractere de texto e estilos de parágrafo e inclui suporte para layout de texto internacional.
Ao contrário de uma API de texto tradicional, o TextFormatter interage com um cliente de layout de texto por meio de um conjunto de funções de retorno. Ele requer que o cliente forneça esses métodos em uma implementação da classe TextSource. O diagrama a seguir ilustra a interação de layout de texto entre o aplicativo cliente e o TextFormatter.
TextFormatter
O formatador de texto é usado para recuperar linhas de texto formatadas do repositório de texto, que é uma implementação de TextSource. Isso é feito criando primeiro uma instância do formatador de texto usando o Create método. Esse método cria uma instância do formatador de texto e define os valores máximos de altura e largura da linha. Assim que uma instância do formatador de texto é criada, o processo de criação de linha é iniciado chamando o FormatLine método. TextFormatter retorna à fonte de texto para recuperar os parâmetros de texto e formatação para os segmentos de texto que formam uma linha.
No exemplo a seguir, o processo de formatação de um repositório de texto é mostrado. O TextFormatter objeto é usado para recuperar linhas de texto do repositório de texto e formatar a linha de texto para desenhar no 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
Implementando o Repositório de Texto do Cliente
Quando você estende o mecanismo de formatação de texto, é necessário implementar e gerenciar todos os aspectos do repositório de texto. Essa não é uma tarefa trivial. O repositório de texto é responsável por acompanhar propriedades de execução de texto, propriedades de parágrafo, objetos inseridos e outro conteúdo semelhante. Ele também fornece ao formatador de texto, objetos individuais TextRun, que são usados para criar objetos TextLine.
Para lidar com a virtualização do repositório de texto, o repositório de texto deve ser derivado de TextSource. TextSource define o método que o formatador de texto usa para recuperar segmentos de texto do repositório de texto. GetTextRun é o método usado pelo formatador de texto para recuperar segmentos de texto usados na formatação de linha. A chamada a GetTextRun é feita repetidamente pelo formatador de texto até que uma das seguintes condições ocorra:
Um TextEndOfLine ou uma subclasse é retornada.
A largura acumulada dos fragmentos de texto excede a largura máxima da linha especificada, seja na chamada para criar o formatador de texto ou na chamada para o método do formatador de texto FormatLine.
Uma sequência de nova linha Unicode, como "CF", "LF" ou "CRLF", é retornada.
Fornecendo segmentos de texto
O núcleo do processo de formatação de texto é a interação entre o formatador de texto e o repositório de texto. A sua implementação de TextSource fornece ao formatador de texto os objetos TextRun e as propriedades com as quais formatar as partes do texto. Essa interação é tratada pelo GetTextRun método, que é chamado pelo formatador de texto.
A tabela a seguir mostra alguns dos objetos predefinidos TextRun .
| Tipo TextRun | Uso |
|---|---|
| TextCharacters | O segmento de texto especializado é usado para transferir uma representação de glifos de caracteres para o formatador de texto. |
| TextEmbeddedObject | A execução de texto especializado usada para fornecer conteúdo no qual a medição, o teste de clique e o desenho são feitos no todo, como um botão ou uma imagem dentro do texto. |
| TextEndOfLine | O fragmento de texto especializado usado para marcar o final de uma linha. |
| TextEndOfParagraph | O trecho de texto especializado utilizado para marcar o término de um parágrafo. |
| TextEndOfSegment | A execução de texto especializado usada para marcar o final de um segmento, como encerrar o escopo afetado por uma execução anterior TextModifier . |
| TextHidden | O segmento de texto especializado usado para marcar uma faixa de caracteres ocultos. |
| TextModifier | Execução de texto especializada utilizada para modificar propriedades de execuções de texto dentro de seu escopo. O escopo se estende até o próximo segmento de texto correspondente TextEndOfSegment ou o próximo TextEndOfParagraph. |
Qualquer objeto predefinido TextRun pode ser subclassificado. Isso permite que sua fonte de texto forneça ao formatador de texto segmentos de texto que incluem dados personalizados.
O exemplo a seguir demonstra um GetTextRun método. Esse repositório de texto retorna TextRun objetos ao formatador de texto para processamento.
// 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
Observação
Neste exemplo, o repositório de texto fornece as mesmas propriedades de texto para todo o texto. Os repositórios de texto avançados precisariam implementar seu próprio gerenciamento de intervalo para permitir que caracteres individuais tenham propriedades diferentes.
Especificando propriedades de formatação
TextRun os objetos são formatados usando as propriedades fornecidas pelo repositório de texto. Essas propriedades vêm em dois tipos, TextParagraphProperties e TextRunProperties. TextParagraphProperties manipular propriedades inclusivas de parágrafo, como TextAlignment e FlowDirection. TextRunProperties são propriedades que podem variar para cada segmento de texto em um parágrafo, como pincéis de primeiro plano Typeface e tamanho da fonte. Para implementar o parágrafo personalizado e os tipos de propriedade de execução de texto personalizado, seu aplicativo deve criar classes que derivam de TextParagraphProperties e TextRunProperties respectivamente.
Consulte também
.NET Desktop feedback