Freigeben über


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

DropDownListWithToolTip.zip

Comments

  • Anonymous
    March 12, 2006
    The topic is nice. But i would like 2 know how can i use it

  • Anonymous
    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 lot

  • Anonymous
    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 me

  • Anonymous
    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. Thanks

  • Anonymous
    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!