Is it possible to change ToolStripMenuItem tooltip

2019-02-17 17:03发布

I have a dynamically filled ContextMenuStrip where each ToolStripMenuItem has a formatted text for the tooltip. And, in order for this text to make sense to the user, I must use a monospaced font, such as "Courier New". The default font is a regular, non Monospaced font. I couldn't find any getter for the ToolTip object nor a way to override its Draw event nor a way to set its style.

So, is it even possible to change ToolStripMenuItem's tooltip font?

Implementing CustomToolTip that inherits from ToolTip doesn't solve the issue, which is passing the new tooltip to ToolStripMenuItem.

3条回答
地球回转人心会变
2楼-- · 2019-02-17 17:32

You could create a custom ToolTip class (CustomToolTip) that inherits from ToolTip. Then you would have to handle the OnDraw event. Inside that event you can change the font.

Look here for an example (there is a vb and c# example).

EDIT

You would have to handle the rendering of the custom tooltip on your own (IE: OnMouseOver, OnMouseLeave events of the toolstripmenuitem). You might be able to create a customtoolstripmenuitem that uses a custom tooltip, but I'm not sure that toolstripmenuitem exposes a tooltip propety/object.

查看更多
做个烂人
3楼-- · 2019-02-17 17:35

I know I'm a little late to the party on this one but you can use reflection to set the instance of ToolTip that is used for rendering the tooltips. After doing that you can just use the Draw method as you normally would.

public void SetToolTipInstance(ToolStrip ts, ToolTip tt)
{
    Type type = ts.GetType.BaseType;
    int propToolTip = Convert.ToInt32(type.GetField("PropToolTip", BindingFlags.NonPublic | BindingFlags.Static).GetValue(ts));
    dynamic ps = type.BaseType.GetProperty("Properties", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(ts);
    ps.GetType.GetMethod("SetObject", BindingFlags.Instance | BindingFlags.Public).Invoke(ps, {propToolTip,tt});
}
查看更多
劳资没心,怎么记你
4楼-- · 2019-02-17 17:39

OK, thanks to Tony Abrams and William Andrus, the solution is as follows:

  • A static instance of ToolTip which initialized.

    toolTip = new ToolTip();
    toolTip.OwnerDraw = true;
    toolTip.Draw += new DrawToolTipEventHandler(tooltip_Draw);
    toolTip.Popup += new PopupEventHandler(tooltip_Popup);    
    toolTip.UseAnimation = true;
    toolTip.AutoPopDelay = 500;
    toolTip.AutomaticDelay = 500;
    
  • ToolTip's Popup event to set its size.

    void tooltip_Popup(object sender, PopupEventArgs e)
    {
        e.ToolTipSize = TextRenderer.MeasureText(toolTipText, new Font("Courier New", 10.0f, FontStyle.Bold));
        e.ToolTipSize = new Size(e.ToolTipSize.Width + TOOLTIP_XOFFSET, e.ToolTipSize.Height + TOOLTIP_YOFFSET);
    }
    
  • ToolTip's Draw event for actual drawing.

    void tooltip_Draw(object sender, DrawToolTipEventArgs e)
    {
    Rectangle bounds = e.Bounds;
    bounds.Offset(TOOLTIP_XOFFSET, TOOLTIP_YOFFSET);
    DrawToolTipEventArgs newArgs = new DrawToolTipEventArgs(e.Graphics, e.AssociatedWindow, e.AssociatedControl, bounds, e.ToolTipText, toolTip.BackColor, toolTip.ForeColor, new Font("Courier New", 10.0f, FontStyle.Bold));
        newArgs.DrawBackground();
        newArgs.DrawBorder();
        newArgs.DrawText(TextFormatFlags.TextBoxControl);
    }
    
  • ToolStripMenuItem's MouseEnter event to show the tooltip.

    System.Windows.Forms.ToolStripMenuItem item = (sender as System.Windows.Forms.ToolStripMenuItem);
    toolTip.SetToolTip(item.Owner, "ToolTipText");
    
查看更多
登录 后发表回答