Reputation: 10619
I am using Graphics.DrawString
to draw my usercontrol's text like this:
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);
}
}
If control's Text
is wider than the DisplayRectangle
, DrawString
nicely breaks the Text
into multiple lines at word boundaries.
Now I want to underline some words from Text
, but I couldn't work it out. I tried splitting the Text
, then MeasureString
the string just before an underlined part starts, DrawString
the normal part, then DrawString
the underlined part. But this works only if Text
is single-line.
I am sure using a child LinkLabel
or RichTextBox
to render my control's text will solve this, but I don't like the idea of using a child control just to underline a few words. Is there another way?
Upvotes: 3
Views: 2634
Reputation: 16899
This is a crude example that will work using the string split into parts and two different font styles, rather than drawing the underline separately ( though that would work too ). In actual practice, I would recommend splitting the text by word, not by phrase, and dealing with each word individually, in a loop. Otherwise, like in this example, the line-breaking doesn't work quite right.
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)
This code can really be cleaned up and made more efficient to let you loop through each word in your text string.
This example also does not include any code to check if you have exceeded the vertical limit of your bounds rectangle.
Sorry for the VB code, I just noticed your question was in C#.
Upvotes: 3