如何:创建空心文字

大多数情况下,在 Windows Presentation Foundation (WPF) 应用程序中向文本字符串添加装饰时,使用的是离散字符集合或字形集合的文本。 例如,可以创建线性渐变画笔并将其应用于 TextBox 对象的 Foreground 属性。 显示或编辑文本框时,线性渐变画笔会自动应用于文本字符串中的当前字符集。

Text displayed with a linear gradient brush

但是,你也可以将文本转换为 Geometry 对象,从而创建其他类型的视觉富文本。 例如,可基于文本字符串的轮廓创建 Geometry 对象。

Text outline using a linear gradient brush

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

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

Text with different colors for fill and stroke

Text with image brush applied to stroke

也可以修改已转换文本的边界框矩形或突出显示。 以下示例说明了通过修改已转换文本的笔划和突出显示来创建视觉效果的方法。

Text with image brush applied to stroke and highlight

示例

使用 FormattedText 对象是将文本转换为 Geometry 对象的关键。 创建此对象后,可以使用 BuildGeometryBuildHighlightGeometry 方法将文本转换为 Geometry 对象。 第一个方法返回格式化文本的几何形状;第二个方法返回格式化文本边界框的几何形状。 以下代码示例介绍如何创建 FormattedText 对象并检索格式化文本及其边界框的几何形状。

/// <summary>
/// Create the outline geometry based on the formatted text.
/// </summary>
public void CreateText()
{
    System.Windows.FontStyle fontStyle = FontStyles.Normal;
    FontWeight fontWeight = FontWeights.Medium;

    if (Bold == true) fontWeight = FontWeights.Bold;
    if (Italic == true) fontStyle = FontStyles.Italic;

    // Create the formatted text based on the properties set.
    FormattedText formattedText = new FormattedText(
        Text,
        CultureInfo.GetCultureInfo("en-us"),
        FlowDirection.LeftToRight,
        new Typeface(
            Font,
            fontStyle,
            fontWeight,
            FontStretches.Normal),
        FontSize,
        System.Windows.Media.Brushes.Black // This brush does not matter since we use the geometry of the text.
        );

    // Build the geometry object that represents the text.
    _textGeometry = formattedText.BuildGeometry(new System.Windows.Point(0, 0));

    // Build the geometry object that represents the text highlight.
    if (Highlight == true)
    {
        _textHighLightGeometry = formattedText.BuildHighlightGeometry(new System.Windows.Point(0, 0));
    }
}
''' <summary>
''' Create the outline geometry based on the formatted text.
''' </summary>
Public Sub CreateText()
    Dim fontStyle As FontStyle = FontStyles.Normal
    Dim fontWeight As FontWeight = FontWeights.Medium

    If Bold = True Then
        fontWeight = FontWeights.Bold
    End If
    If Italic = True Then
        fontStyle = FontStyles.Italic
    End If

    ' Create the formatted text based on the properties set.
    Dim formattedText As New FormattedText(Text, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, New Typeface(Font, fontStyle, fontWeight, FontStretches.Normal), FontSize, Brushes.Black) ' This brush does not matter since we use the geometry of the text.

    ' Build the geometry object that represents the text.
    _textGeometry = formattedText.BuildGeometry(New Point(0, 0))

    ' Build the geometry object that represents the text highlight.
    If Highlight = True Then
        _textHighLightGeometry = formattedText.BuildHighlightGeometry(New Point(0, 0))
    End If
End Sub

为显示检索到的 Geometry 对象,需访问显示已转换文本的对象的 DrawingContext。 在这些代码示例中,通过创建从支持用户定义呈现的类派生的自定义控件对象来实现此访问。

若要在自定义控件中显示 Geometry 对象,请重写 OnRender 方法。 重写的方法应使用 DrawGeometry 方法来绘制 Geometry 对象。

/// <summary>
/// OnRender override draws the geometry of the text and optional highlight.
/// </summary>
/// <param name="drawingContext">Drawing context of the OutlineText control.</param>
protected override void OnRender(DrawingContext drawingContext)
{
    // Draw the outline based on the properties that are set.
    drawingContext.DrawGeometry(Fill, new System.Windows.Media.Pen(Stroke, StrokeThickness), _textGeometry);

    // Draw the text highlight based on the properties that are set.
    if (Highlight == true)
    {
        drawingContext.DrawGeometry(null, new System.Windows.Media.Pen(Stroke, StrokeThickness), _textHighLightGeometry);
    }
}
''' <summary>
''' OnRender override draws the geometry of the text and optional highlight.
''' </summary>
''' <param name="drawingContext">Drawing context of the OutlineText control.</param>
Protected Overrides Sub OnRender(ByVal drawingContext As DrawingContext)
    ' Draw the outline based on the properties that are set.
    drawingContext.DrawGeometry(Fill, New Pen(Stroke, StrokeThickness), _textGeometry)

    ' Draw the text highlight based on the properties that are set.
    If Highlight = True Then
        drawingContext.DrawGeometry(Nothing, New Pen(Stroke, StrokeThickness), _textHighLightGeometry)
    End If
End Sub

有关示例自定义用户控件对象的源,请参阅适用于 C# 的 OutlineTextControl.cs适用于 Visual Basic 的 OutlineTextControl.vb

另请参阅