Tooltip for each items in a combo box

Senthil picture Senthil · Mar 25, 2009 · Viewed 55.6k times · Source

I just want to add a tooltip for each item in a combo box. i am using c#.net windows application.

There is no option like

combobox.items[1].tooltip();

Is there any way to add tooltip it ?

Answer

Michael Sorens picture Michael Sorens · Feb 19, 2011

There are actually a couple reasonable solutions to this question. An MSDN forum has a ComboBox Item highlight event post that contains two possibilities, one from nobugz and one from agrobler. Each of them provides code to subclass a ComboBox that is supposed to handle tool tips on individual items in the ComboBox's dropdown. Agrobler's solution looks more polished, in that he/she even includes some nice illustrations, but unfortunately it is not clear (at least to me) how to populate the crucial ToolTipMember property of the control.

Both of these solutions appear to allow arbitrary tooltips assigned to individual items. A more specific, but more common case, is where you simply want the tooltip to mirror the text of the item, when you know you may have items that are too long to fit the width of the ComboBox. In my own case, I have an instance of a ComboBox that holds complete file paths so it is easy to see where the contents could exceed the ComboBox's width.

Zhi-Xin Ye, in the MSDN forum post Windows Dropdown question, provides a solution that addresses this more specific problem and is much simpler. I reproduce the code here in its entirety. (Note that this code presupposes you have created a Form called Form1 and hooked up the load handler shown, and also added a ComboBox named comboBox1 and a tool tip handler toolTip1.)

private void Form1_Load(object sender, EventArgs e)
{
    this.comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
    this.comboBox1.DrawItem += new DrawItemEventHandler(comboBox1_DrawItem);
}

void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    string text = this.comboBox1.GetItemText(comboBox1.Items[e.Index]);
    e.DrawBackground();
    using (SolidBrush br = new SolidBrush(e.ForeColor))
    { e.Graphics.DrawString(text, e.Font, br, e.Bounds); }

    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
    { this.toolTip1.Show(text, comboBox1, e.Bounds.Right, e.Bounds.Bottom); }
    else { this.toolTip1.Hide(comboBox1); }
    e.DrawFocusRectangle();
}

While simple and concise, this code does suffer from one defect (as is pointed out in a reply on the above MSDN thread): as you move the mouse (without clicking) from one dropdown item to the next, only every other one shows a persistent tooltip! The fix is only hinted at by yet another entry on that thread, so I thought it would be useful to provide the full, corrected code here:

private void Form1_Load(object sender, EventArgs e)
{
    comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
    comboBox1.DrawItem += comboBox1_DrawItem;
    comboBox1.DropDownClosed += comboBox1_DropDownClosed;
}

private void comboBox1_DropDownClosed(object sender, EventArgs e)
{
    toolTip1.Hide(comboBox1);
}

private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0) { return; } // added this line thanks to Andrew's comment
    string text = comboBox1.GetItemText(comboBox1.Items[e.Index]);
    e.DrawBackground();
    using (SolidBrush br = new SolidBrush(e.ForeColor))
    { e.Graphics.DrawString(text, e.Font, br, e.Bounds); }
    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
    { toolTip1.Show(text, comboBox1, e.Bounds.Right, e.Bounds.Bottom); }
    e.DrawFocusRectangle();
}

Besides removing a few redundant portions of code (e.g. the "this" qualifier) the primary difference is moving the toolTip1.Hide call into the DropDownClosed event handler. Taking it out of the DrawItem handler eliminates the defect mentioned above; but then you need to close it when the drop down closes, otherwise the last displayed tooltip will remain onscreen.

2012.07.31 Addendum

Just wanted to mention that I have since created a composite ComboBox that incorporates this tooltip capability so if you use my library you have no code to write at all. Just drag a ComboBoxWithTooltip onto the Visual Studio designer and you are done. Drill down to ComboBoxWithTooltip on my API page or download my open-source C# library to get started. (Note that the patch for the bug Andrew caught will be in release 1.1.04, due out soon.)