Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
140 views
in Technique[技术] by (71.8m points)

c# - How to increase ToolTip Rectangle size

I am currently implementing a tooltip which has at least two sentences worth inside of it, so I need to somehow create a large rectangle which would hold it.

My issue is the height of the rectangle.

Snip:

enter image description here

As you can see the green rectangle does not have the required size.

Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Discounting.Module
{
    public partial class Benefits : UserControl
    {
        public Benefits()
        {
            InitializeComponent();
        }

        private void ToolTip1_Draw(object sender, DrawToolTipEventArgs e)
        {
            var newEventArgs = new DrawToolTipEventArgs(
                e.Graphics,
                e.AssociatedWindow,
                e.AssociatedControl,
                e.Bounds, e.ToolTipText,
                this.BackColor,
                this.ForeColor,
                Font);

            DrawToolTip(e);
        }

        private void DrawToolTip(DrawToolTipEventArgs e)
        {
            using (var sf = new StringFormat())
            {
                sf.LineAlignment = StringAlignment.Center;

                sf.Alignment = StringAlignment.Center;


                using (var graphics = e.Graphics)
                {

                    var linearGradientBrush = new LinearGradientBrush(new Rectangle(e.Bounds.X, e.Bounds.Y,
                        8000, 1000), Color.GreenYellow, Color.MintCream, 45f);

                    graphics.FillRectangle(linearGradientBrush, linearGradientBrush.Rectangle);

                    graphics.DrawString(e.ToolTipText, new Font("Aerial",12.0f, FontStyle.Bold), Brushes.Silver,
                        new PointF(linearGradientBrush.Rectangle.X + 6, linearGradientBrush.Rectangle.Y + 6)); // shadow layer
                    graphics.DrawString(e.ToolTipText, new Font("Aerial",12.0f, FontStyle.Bold), Brushes.Black,
                        new PointF(linearGradientBrush.Rectangle.X + 5, linearGradientBrush.Rectangle.Y + 5)); // top layer

                    linearGradientBrush.Dispose();
                }
            }
        }

        private void ToolTip2_Draw(object sender, DrawToolTipEventArgs e)
        {
            DrawToolTip(e);
        }

        private void ToolTip3_Draw(object sender, DrawToolTipEventArgs e)
        {
            DrawToolTip(e);
        }

        private void ToolTip4_Draw(object sender, DrawToolTipEventArgs e)
        {
            DrawToolTip(e);
        }
    }
}

If you require further details I would be happy to provide them.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

ToolTip Custom Drawing

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);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...