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 (19)

  1. The topic is nice. But i would like 2 know how can i use it

  2. irenake says:

    To populate items, use Add(text, value, tooltip) method.  The rest is same as WinForms ComboBox.

  3. Rakesh Mukundan says:

    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.

  4. irenake says:

    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…

  5. Rakesh Mukundan says:

    Thank you sir. I got it and it is working fine.

    once more thank you. Really ur code sample helped me a lot

  6. Moglee says:

    This is really cool? Are you aware of/planning similar work on web control ( Drodownlist with tooltip on aspx pages?)

  7. irenake says:

    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…

  8. Megastar says:

    Wow ! Really great topic. But I want the same thing in ASP using Javascript. Is it possible ?

    Please try it for me

  9. Sushmitha.T says:

    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??

  10. irenake says:

    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…

  11. siLver says:

    Hihi,

    I like to know if codes for asp .net is out ^^.

    How will asp .net be different from asp .net ajax..

  12. Blazing Prabhu says:

    I want to do the same in web application. Is it possible in web?. Please some one help me and give the solution.

  13. Snehal says:

    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

  14. ratheesh vijay says:

    can u plz show me how to make the tooltip in asp.net1.1?

  15. Kadambari says:

    Did u get chance to implement similar thing

    on web control ( Drodownlist with tooltip on aspx pages?)

    I want it.Urgent!!

  16. Srikanth Marri says:

    can u plz show me how to make the tooltip in asp.net2.0?

  17. Surya says:

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

  18. Xander says:

    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.

  19. Scott Ferguson says:

    Well done!