绘制格式化文本

本主题概述了 FormattedText 对象的功能。 此对象为在 Windows Presentation Foundation (WPF) 应用程序中绘制文本提供低级别控制。

技术概述

使用 FormattedText 对象可以绘制多行文本,可对文本中的每个字符单独设置格式。 下例演示应用了多种格式的文本。

Text displayed using FormattedText object

注意

对于从 Win32 API 迁移的开发人员,Win32 迁移一节中的表列出了 Win32 DrawText 标志和 Windows Presentation Foundation (WPF) 中的近似等效项。

使用格式化文本的原因

WPF 包括多个用于在屏幕中绘制文本的控件。 每个控件都面向不同的方案,并具有自己的功能和限制列表。 通常,当需要支持有限的文本时应使用 TextBlock 元素,例如需要句子简短的用户界面 (UI)。 当需要最少的文本支持时,可以使用 Label。 有关详细信息,请参阅 WPF 中的文档

FormattedText 对象提供的文本格式设置功能比 Windows Presentation Foundation (WPF) 文本控件提供的相应功能更强大,并且在要将文本用作装饰元素时很有用。 有关详细信息,请参阅下一节将格式化文本转换为几何图形

此外,对于创建面向文本的 DrawingVisual 派生的对象,FormattedText 对象非常有用。 DrawingVisual 是一个轻量绘图类,用于绘制形状、图像或文本。 有关详细信息,请参阅使用 DrawingVisuals 执行测试示例

使用 FormattedText 对象

若要创建格式化文本,请调用 FormattedText 构造函数来创建 FormattedText 对象。 创建初始格式化文本字符串后,便可应用某一范围的格式样式。

使用 MaxTextWidth 属性将文本限制在特定宽度。 文本将自动换行,避免超过指定宽度。 使用 MaxTextHeight 属性将文本限制在特定高度。 超过指定高度的文本将显示一个省略号“…”。

Text displayed with wordwrap and ellipsis.

可向一个或多个字符应用多种格式样式。 例如,可以同时调用 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

字号度量单位

如同 Windows Presentation Foundation (WPF) 应用程序中的其他文本对象,FormattedText 对象使用与设备无关的像素作为度量单位。 但是,大多数 Win32 应用程序使用分作为度量单位。 如果要在 Windows Presentation Foundation (WPF) 应用程序中使用以分为单位的显示文本,则需要将与设备无关的单位(每单位 1/96 英寸)转换为分。 以下代码示例演示如何执行此转换。

// The font size is calculated in terms of points -- not as device-independent pixels.
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5);
' The font size is calculated in terms of points -- not as device-independent pixels.
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5)

将格式化文本转换为几何图形

可将格式化文本转换为 Geometry 对象,这样便可以创建其他类型的悦目文本。 例如,可基于文本字符串的轮廓创建 Geometry 对象。

Text outline using a linear gradient brush

以下示例说明了几种通过修改已转换文本的笔划、填充和突出显示来创建悦目的视觉效果的方法。

Text with different colors for fill and stroke

Text with image brush applied to stroke

Text with image brush applied to stroke and highlight

将文本转换为 Geometry 对象时,它不再是字符的集合,也就是说不能修改文本字符串中的字符。 但是,可修改已转换文本的笔划和填充属性,以此来影响该文本的外观。 笔划是指已转换文本的轮廓;填充是指已转换文本的轮廓的内部区域。 有关详细信息,请参阅创建轮廓文本

还可将格式化文本转换为 PathGeometry 对象,并使用此对象突出显示文本。 例如,可将动画应用于 PathGeometry 对象,使此动画沿着格式化文本的轮廓显示。

以下示例显示已转换为 PathGeometry 对象的格式化文本。 经过动画处理的椭圆会沿着所呈现文本的笔划路径显示。

Sphere following the path geometry of text
沿着文本路径几何图形运动的球

有关详细信息,请参阅如何:为文本创建 PathGeometry 动画

将格式化文本转换为 PathGeometry 对象后,可为其创建其他有趣的用法。 例如,可剪辑视频,以便在格式化文本中显示。

Video displaying in the path geometry of text

Win32 迁移

FormattedText 用于绘制文本的功能与 Win32 DrawText 函数的功能相似。 对于从 Win32 API 迁移的开发人员,下表列出了 Win32 DrawText 标志和 Windows Presentation Foundation (WPF) 中的近似等效项。

DrawText 标志 WPF 等效项 说明
DT_BOTTOM Height 使用 Height 属性计算相应的 Win32 DrawText“y”位置。
DT_CALCRECT HeightWidth 使用 HeightWidth 属性计算输出矩形。
DT_CENTER TextAlignment 使用值设置为 CenterTextAlignment 属性。
DT_EDITCONTROL 不要求。 间距宽度和最后一行的呈现与框架编辑控件中的相同。
DT_END_ELLIPSIS Trimming 使用值为 CharacterEllipsisTrimming 属性。

使用 WordEllipsis 来获取带有 DT_WORD_ELIPSIS 尾部省略号的 Win32 DT_END_ELLIPSIS;在这种情况下,省略号字符仅出现在一行容不下的字词中。
DT_EXPAND_TABS 不要求。 制表符自动扩展为在每 4 个 em 后停止,这大约为 8 个与语言无关的字符的宽度。
DT_EXTERNALLEADING 不要求。 行距中始终包括外部间隙。 使用 LineHeight 属性创建用户定义的行距。
DT_HIDEPREFIX 不支持。 在构造 FormattedText 对象之前,从字符串中删除“&”。
DT_LEFT TextAlignment 这是默认文本对齐方式。 使用值设置为 LeftTextAlignment 属性。 (仅限 WPF)
DT_MODIFYSTRING 不支持。
DT_NOCLIP VisualClip 剪辑不会自动发生。 如果要剪切文本,请使用 VisualClip 属性。
DT_NOFULLWIDTHCHARBREAK 不支持。
DT_NOPREFIX 不要求。 字符串中的“&”字符始终作为正常字符处理。
DT_PATHELLIPSIS 使用值为 WordEllipsisTrimming 属性。
DT_PREFIX 不支持。 如果想在文本(例如快捷键或链接)中使用下划线,请使用 SetTextDecorations 方法。
DT_PREFIXONLY 不支持。
DT_RIGHT TextAlignment 使用值设置为 RightTextAlignment 属性。 (仅限 WPF)
DT_RTLREADING FlowDirection FlowDirection 属性设置为 RightToLeft
DT_SINGLELINE 不要求。 FormattedText 对象表现为单行控件,除非设置了 MaxTextWidth 属性或文本包含回车/换行 (CR/LF) 字符。
DT_TABSTOP 不支持用户定义的制表位位置。
DT_TOP Height 不要求。 上对齐是默认设置。 其他垂直定位值可通过使用 Height 属性计算相应的 Win32 DrawText“y”位置来定义。
DT_VCENTER Height 使用 Height 属性计算相应的 Win32 DrawText“y”位置。
DT_WORDBREAK 不要求。 使用 FormattedText 对象会自动发生断字。 无法禁用它。
DT_WORD_ELLIPSIS Trimming 使用值为 WordEllipsisTrimming 属性。

另请参阅