SYSK 23: DropDownList with ToolTip that Automatically Shows Up as You Mouse-Over the Items in the Dropped Down List
Ever wished you had a freeware DropDownList control that, instead of having one hardcoded tool tip, changed the tool tip text as the user moves from item to item in the dropped down list? Well, your wait is over. I’m enclosing the code for such a control below.
Warning: all disclaimers apply! Also, it’s intended to be a “starter” code; i.e. you could (and should) certainly add DataSource implementation to avoid using Add method in the loop…
You create and initialize the control same way you would the standard Windows Forms ComboBox. To add items to the list, call
YourControlName.Add("item text", itemValue, "item tool tip");
Enjoy!
SourceCode:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace YourCompany.WinControls
{
public class DropDownListWithToolTip : ComboBox
{
private bool _droppedDown = false;
private System.Collections.Generic.List<string> _toolTips = new List<string>();
private int _prevDrawIndex = -1;
private ToolTip _tip = new ToolTip();
public DropDownListWithToolTip()
: base()
{
this.DisplayMember = "Key";
this.ValueMember = "Value";
this.DropDownStyle = ComboBoxStyle.DropDownList;
this.DropDown += new EventHandler(DropDownListWithToolTip_DropDown);
this.DropDownClosed += new EventHandler(DropDownListWithToolTip_DropDownClosed);
base.DrawMode = DrawMode.OwnerDrawFixed;
_tip.AutomaticDelay = 0;
_tip.AutoPopDelay = 10000;
_tip.InitialDelay = 10;
_tip.IsBalloon = true;
_tip.ReshowDelay = 10;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
object item;
if (e.Index >= 0)
{
if (e.Index < Items.Count)
item = Items[e.Index];
else
item = this.Text;
Rectangle bounds = e.Bounds;
int border = 1;
int height = Font.Height + 2 * border;
Rectangle textBounds = new Rectangle(
bounds.X + (border * 2),
bounds.Y,
bounds.Width - (border * 2),
bounds.Height);
if (RightToLeft == RightToLeft.Yes)
{
// For a RightToLeft checked list box, we want the text
// to be drawn at the left.
// So we override the X position.
textBounds.X = bounds.X;
}
// Setup text font, color, and text
string text = "";
Color backColor = BackColor;
Color foreColor = ForeColor;
if (!Enabled)
{
foreColor = SystemColors.GrayText;
}
Font font = Font;
object value = FilterItemOnProperty(item);
if (value != null)
{
text = value.ToString();
}
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
backColor = SystemColors.Highlight;
foreColor = SystemColors.HighlightText;
}
// Draw the text
using (Brush b = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(b, textBounds);
}
Rectangle stringBounds = new Rectangle(
textBounds.X + 1,
textBounds.Y + border,
textBounds.Width - 1,
textBounds.Height - border * 2);
using (StringFormat format = new StringFormat())
{
// Adjust string format for Rtl controls
if (RightToLeft == RightToLeft.Yes)
{
format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
}
format.FormatFlags |= StringFormatFlags.NoWrap;
// Do actual drawing
using (SolidBrush brush = new SolidBrush(foreColor))
{
e.Graphics.DrawString(text, font, brush, stringBounds, format);
}
}
// Draw the focus rect if required
if ((e.State & DrawItemState.Focus) == DrawItemState.Focus &&
(e.State & DrawItemState.NoFocusRect) != DrawItemState.NoFocusRect)
{
ControlPaint.DrawFocusRectangle(e.Graphics, textBounds, foreColor, backColor);
}
}
if (this.DesignMode == false && e.Index != -1 && ((e.State & DrawItemState.Selected) == DrawItemState.Selected))
{
if (_droppedDown == true && _prevDrawIndex != e.Index)
{
_tip.Show(_toolTips[e.Index], this);
_prevDrawIndex = e.Index;
}
}
}
void DropDownListWithToolTip_DropDownClosed(object sender, EventArgs e)
{
_droppedDown = false;
_tip.Hide(this);
}
void DropDownListWithToolTip_DropDown(object sender, EventArgs e)
{
_droppedDown = true;
}
public void Add(string text, object value, string toolTip)
{
base.Items.Add(new KeyValuePair<string, object>(text, value));
_toolTips.Add(toolTip);
}
public new KeyValuePair<string, object> SelectedItem
{
get
{
KeyValuePair<string, object> result = new KeyValuePair<string,object>();
if (this.SelectedIndex != -1)
result = (KeyValuePair<string, object>)base.SelectedItem;
return result;
}
}
public new string SelectedText
{
get
{
string result = "";
if (this.SelectedIndex != -1)
result = SelectedItem.Key;
return result;
}
}
public new object SelectedValue
{
get
{
object result = null;
if (this.SelectedIndex != -1)
result = SelectedItem.Value;
return result;
}
}
public string ToolTip(int index)
{
string result = "";
if (index >= 0 && index < _toolTips.Count)
result = _toolTips[index];
return result;
}
}
}
Comments
Anonymous
March 12, 2006
The topic is nice. But i would like 2 know how can i use itAnonymous
March 13, 2006
To populate items, use Add(text, value, tooltip) method. The rest is same as WinForms ComboBox.Anonymous
March 14, 2006
How can i add this control to my project. I tried a lot and i didnt get a clue. I am able to add the class and i used the
Add(text, value, tooltip) method, but i am unable to view the control in my form . Can u pls helo me in this.Anonymous
March 15, 2006
I've posted a sample project. The form_load method populates the dropdown. All you need to do is run it, and then drop down the list and mouse over the items...Anonymous
March 15, 2006
Thank you sir. I got it and it is working fine.
once more thank you. Really ur code sample helped me a lotAnonymous
April 20, 2006
This is really cool? Are you aware of/planning similar work on web control ( Drodownlist with tooltip on aspx pages?)Anonymous
April 21, 2006
Thanks. No, I haven't seen it done anywhere else... I'll put it on my list of things to work on, but not sure when I'll get to it...Anonymous
December 22, 2006
Wow ! Really great topic. But I want the same thing in ASP using Javascript. Is it possible ? Please try it for meAnonymous
February 19, 2007
Hi irenak , I tried to implement the same in asp.net but unable to do it. Do u have any idea how to do the same in asp.net??Anonymous
February 19, 2007
If/when I get some time and implement it, I'll post the solution. For now, perhaps look at ASP.NET AJAX to help you with the client side JavaScript...Anonymous
February 28, 2007
Hihi, I like to know if codes for asp .net is out ^^. How will asp .net be different from asp .net ajax..Anonymous
May 13, 2007
I want to do the same in web application. Is it possible in web?. Please some one help me and give the solution.Anonymous
August 03, 2007
Hi! This is really good. But this works for windows forms. In web forms private ToolTip _tip = new ToolTip(); this is not available. Can you tell me how this can be fixed. ThanksAnonymous
December 13, 2007
can u plz show me how to make the tooltip in asp.net1.1?Anonymous
April 13, 2008
Did u get chance to implement similar thing on web control ( Drodownlist with tooltip on aspx pages?) I want it.Urgent!!Anonymous
April 17, 2008
can u plz show me how to make the tooltip in asp.net2.0?Anonymous
July 09, 2008
when i bind the combobox with displaymember and value memeber how can make use of this tooltip apart from this following type combobox1.Add("item text", itemValue, "item tool tip");Anonymous
October 15, 2008
Sigh...just once I wish I could find my solution in VB.net instead of these c# examples. I don't suppose you have a sample of how to accomplish this in vb.net? For those smart guys out there, yes I could take the time to try and duplicate in vb but frankly I just don't have the time to learn c# well enough to then translate it into something similar in vb.net.Anonymous
October 24, 2015
Well done!