Align text vertically with VisualStyleRenderer for VisualStyleElement.ToolTip.Standard.Normal
I'm creating a custom ToolTip
that will bold the first line of text if the text is multi-line. I'm also using the VisualStyleRenderer
to draw the tool tip correctly with styles. However, when I draw the text (even with TextFormatFlags.VerticalCenter
set), it draws at the top of 开发者_JAVA百科the box. I was going to just bump the bounding box down 2 pixels (which fixed it on Windows 7) but I wasn't 100% sure how portable that would be to another OS. Does anyone know how to draw the text vertically centered correctly?
EDIT: To make this clear, I know this code doesn't bold the first line. I'm trying to first replicate a standard tooltip, and then afterwards do the bolding.
public class BoldedFirstLineToolTip : ToolTip
{
public BoldedFirstLineToolTip()
{
this.OwnerDraw = true;
this.Draw += new DrawToolTipEventHandler(OnDraw);
}
private void OnDraw(object sender, DrawToolTipEventArgs e)
{
// Try to draw using the visual style renderer.
if (VisualStyleRenderer.IsElementDefined(VisualStyleElement.ToolTip.Standard.Normal))
{
var renderer = new VisualStyleRenderer(VisualStyleElement.ToolTip.Standard.Normal);
renderer.DrawBackground(e.Graphics, e.Bounds);
var b = e.Bounds;
// b.Y + 2 // This works when using e.Graphics.DrawString.
renderer.DrawText(e.Graphics, b, e.ToolTipText, false /*drawDisabled*/,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
else
{
// Fall back to non-visual style drawing.
e.DrawBackground();
e.DrawBorder();
e.DrawText();
}
}
}
I've decided to just use padding fixes. I've provided my full solution below. I tested on both XP and Windows 7.
public class BoldedFirstLineToolTip : ToolTip
{
public BoldedFirstLineToolTip()
{
this.OwnerDraw = true;
this.Draw += new DrawToolTipEventHandler(OnDraw);
}
private void OnDraw(object sender, DrawToolTipEventArgs e)
{
// Try to draw using the visual style renderer.
if (VisualStyleRenderer.IsSupported && VisualStyleRenderer.IsElementDefined(VisualStyleElement.ToolTip.Standard.Normal))
{
var bounds = e.Bounds;
var renderer = new VisualStyleRenderer(VisualStyleElement.ToolTip.Standard.Normal);
renderer.DrawBackground(e.Graphics, bounds);
var color = renderer.GetColor(ColorProperty.TextColor);
var text = e.ToolTipText;
using (var textBrush = new SolidBrush(renderer.GetColor(ColorProperty.TextColor)))
using (var font = e.Font)
{
// Fix the positioning of the bounds for the text rectangle.
var rendererBounds = new Rectangle(e.Bounds.X + 6, e.Bounds.Y + 2, e.Bounds.Width - 6 * 2, e.Bounds.Height - 2 * 2);
if (!text.Contains('\n'))
{
renderer.DrawText(e.Graphics, rendererBounds, text);
}
else
{
var lines = text.Split('\n').Select(l => l.Trim());
var first = lines.First();
var otherLines = Environment.NewLine + String.Join(Environment.NewLine, lines.Skip(1).ToArray());
// Draw the first line.
using (var boldFont = new Font(font, FontStyle.Bold))
{
e.Graphics.DrawString(first, boldFont, textBrush, rendererBounds.X - 1, rendererBounds.Y - 1);
}
renderer.DrawText(e.Graphics, rendererBounds, otherLines, false /*drawDisabled*/, TextFormatFlags.Left);
}
}
}
else
{
// Fall back to non-visual style drawing.
e.DrawBackground();
e.DrawBorder();
using (var sf = new StringFormat())
{
sf.LineAlignment = StringAlignment.Center;
e.Graphics.DrawString(e.ToolTipText, SystemFonts.DialogFont, Brushes.Black, e.Bounds, sf);
}
}
}
}
精彩评论