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