Well, since there might be some quirks when mixing TextRenderer
and the Graphics
object, here's an example:
The ToolTip.PopUp event provides means to set the Size of the ToolTip rectangle. You just need to measure the Text and set its PopupEventArgs.ToolTipSize property to the measured Size.
This allows to use multi-line strings as well, using Environment.NewLine to separate the lines.
The PopupEventArgs
object doesn't provide a Graphics
object that can be use to measure the Text. We can use TextRenderer.MeasureText instead.
TextRenderer.MeasureText
is very precise: it will give back the exact measure of the Text. Since you are using Graphics.DrawString
to draw the Text, we better be generous and add some more space to the measured Width, to avoid text wrapping and also because the Text looks better if the container rectangle is not too tight.
In the Popup event, after measuring the Text, I'm adding 5 pixels to both the Width and Height (Size.Add([Measured Size], new Size(5, 5))
). Modify as required
Note:
Here, the Font family and Size are hard-coded. Of course you may want to use a more dynamic Font object, possibly linked to a property of your UserControl
. The Font can be changed at any time: the PopUp
event will use it to measure the test bounds.
TextFormatFlags toolTipFlags = TextFormatFlags.VerticalCenter |
TextFormatFlags.LeftAndRightPadding | TextFormatFlags.HorizontalCenter | TextFormatFlags.NoClipping;
Font toolTipFont = new Font("Arial", 12.0f, FontStyle.Bold);
private void toolTip1_Popup(object sender, PopupEventArgs e)
{
string toolTipText = (sender as ToolTip).GetToolTip(e.AssociatedControl);
using (var g = e.AssociatedControl.CreateGraphics()) {
var textSize = Size.Add(TextRenderer.MeasureText(
g, toolTipText, toolTipFont, Size.Empty, flags), new Size(10, 5));
e.ToolTipSize = textSize;
}
}
private void toolTip1_Draw(object sender, DrawToolTipEventArgs e) => DrawToolTip(e);
private void DrawToolTip(DrawToolTipEventArgs e)
{
using (var linearGradientBrush = new LinearGradientBrush(e.Bounds, Color.GreenYellow, Color.MintCream, 45f)) {
e.Graphics.FillRectangle(linearGradientBrush, e.Bounds);
}
var shadowBounds = new Rectangle(new Point(e.Bounds.X + 1, e.Bounds.Y + 1), e.Bounds.Size);
TextRenderer.DrawText(e.Graphics, e.ToolTipText, toolTipFont, shadowBounds, Color.LightGray, toolTipFlags);
TextRenderer.DrawText(e.Graphics, e.ToolTipText, toolTipFont, e.Bounds, Color.Black, toolTipFlags);
}