如何用GDI强调多行文本的某些部分?

时间:2009-10-30 15:05:56

标签: c# .net graphics gdi+

我正在使用Graphics.DrawString来绘制我的usercontrol文本,如下所示:

protected override void OnPaint(PaintEventArgs e)
{
    RectangleF bounds = DisplayRectangle;
    bounds.Inflate(-4, -4); // Padding
    StringFormat format = new StringFormat();
    format.Alignment = StringAlignment.Near;
    format.LineAlignment = StringAlignment.Near;
    format.Trimming = StringTrimming.None;
    using (Brush bFore = new SolidBrush(ForeColor))
    {
        g.DrawString(Text, Font, bFore, bounds, format);
    }
}

如果控件的TextDisplayRectangle宽,DrawString可以很好地将Text分成多个单词边界线。

现在我想强调来自Text的一些词,但我无法解决。我尝试拆分Text,然后MeasureString字符串在下划线部分开始之前,DrawString正常部分,然后DrawString下划线部分。但这仅在Text为单行时才有效。

我确信使用小孩LinkLabelRichTextBox来渲染我的控件的文字会解决这个问题,但我不喜欢使用子控件来强调几个单词。还有另一种方式吗?

1 个答案:

答案 0 :(得分:3)

这是一个粗略的例子,可以使用分割成部分和两种不同字体样式的字符串,而不是单独绘制下划线(尽管这也可以)。在实际操作中,我建议逐个单词,而不是按短语分割文本,并在循环中单独处理每个单词。否则,就像在这个例子中一样,换行不正常。

Dim fntNormal As New Font(myFontFamily, myFontSize, FontStyle.Regular, GraphicsUnit.Pixel)
  Dim fntUnderline As New Font(myFontFamily, myFontSize, FontStyle.Underline, GraphicsUnit.Pixel)

  g.DrawString("This is ", fntNormal, Brushes.Black, rctTextArea)
  w1 = g.MeasureString("This is ", fntNormal).Width
  w2 = g.MeasureString("underlined", fntUnderline).Width
  If w1 + w2 > rctTextArea.Width Then
     yPos = rctTextArea.Y + g.MeasureString("This is ", fntNormal).Height + 5
     xPos = rctTextArea.X
  Else
     yPos = rctTextArea.Y
     xPos = 0
  End If

  g.DrawString("underlined", fntUnderline, Brushes.Black, xPos, yPos)

  w1 = g.MeasureString("underlined", fntUnderline).Width
  w2 = g.MeasureString(", and this is not.", fntNormal).Width

  If w1 + w2 > rctTextArea.Width Then
     yPos += g.MeasureString("underlined", fntUnderline).Height + 5
     xPos = rctTextArea.X
  Else
     xPos = 0
  End If


  g.DrawString(", and this is not.", fntNormal, Brushes.Black, xPos, yPos)

这段代码可以真正清理并提高效率,让您循环浏览文本字符串中的每个单词。

此示例也不包含任何代码,用于检查是否超出了边界矩形的垂直限制。

对不起VB代码,我刚注意到你的问题是在C#中。