ToolTip in Custom ComboBox DropDown

I have a Custom ComboBox that I'm creating...

I've already implemented everything I need, but I have 1 more task...

I would like to show a tooltip when the list is dropped down to show more information...

What I need is to be able to determine which item the mouse is over when the list is dropped down.

I noticed this similar question:

However, the issue of ascertaining which item the mouse was over was never resolved.


LVL 14
Who is Participating?
Okay here goes... this is my code for a custom ComboBox verbatim...  let me know how it goes for you... it worked fine for my application :)

It adds an event to the ComboBox called "Hover" which is fired everytime the item highlighted in the dropdown list changes.  

If you have any problems let me know!


using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;

namespace Custom
    /// <summary>
    /// Class that contains data for the hover event
    /// </summary>
    public class HoverEventArgs : EventArgs
        private int _itemIndex = 0;
        public int itemIndex
                return _itemIndex;
                _itemIndex = value;

    /// <summary>
    /// Delegate declaration
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void HoverEventHandler(object sender, HoverEventArgs e);

    /// <summary>
    /// Derived ComboBox that shows current position of the cursor inside the drop down
    /// as it's actually moving around in there.  This combobox will raise the custom
    /// event we have defined above whenever a new item is hovered over in the drop down list
    /// </summary>
    class MyComboBox : ComboBox
        // Internal variables to hold the mouse position and the control
        // position for calculating whether the mouse is inside the drop down
        // and whether we scrolled with the mouse inside the drop down
        private int yPos = 0;
        private int xPos = 0;
        private int scrollPos = 0;
        private int xFactor = -1;

        // Import the GetScrollInfo function from user32.dll
        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetScrollInfo(IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo);
        // Win32 constants
        private const int SB_VERT = 1;
        private const int SIF_TRACKPOS = 0x10;
        private const int SIF_RANGE = 0x1;
        private const int SIF_POS = 0x4;
        private const int SIF_PAGE = 0x2;
        private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;

        private const int SCROLLBAR_WIDTH = 17;
        private const int LISTBOX_YOFFSET = 21;

        // Return structure for the GetScrollInfo method
        private struct ScrollInfoStruct
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;

        public event HoverEventHandler Hover;

        protected virtual void OnHover(HoverEventArgs e)
            HoverEventHandler handler = Hover;
            if (handler != null)
                // Invokes the delegates.
                handler(this, e);

        //Capture messages coming to our combobox
        protected override void WndProc(ref Message msg)
            //This message code indicates the value in the list is changing
            if (msg.Msg == 308)
                int onScreenIndex = 0;

                // Get the mouse position relative to this control
                Point LocalMousePosition = this.PointToClient(Cursor.Position);
                xPos = LocalMousePosition.X;
                yPos = LocalMousePosition.Y - this.Size.Height - 1;

                // save our y position which we need to ensure the cursor is
                // inside the drop down list for updating purposes
                int oldYPos = yPos;

                // get the 0-based index of where the cursor is on screen
                // as if it were inside the listbox
                while (yPos >= this.ItemHeight)
                    yPos -= this.ItemHeight;

                //if (yPos < 0) { onScreenIndex = -1; }

                ScrollInfoStruct si = new ScrollInfoStruct();
                si.fMask = SIF_ALL;
                si.cbSize = Marshal.SizeOf(si);
                // msg.LParam holds the hWnd to the drop down list that appears
                int k = GetScrollInfo(msg.LParam, SB_VERT, ref si);

                // k returns 0 on error, so if there is no error add the current
                // track position of the scrollbar to our index
                if (k > 0)
                    onScreenIndex += si.nTrackPos;

                // Check we're actually inside the drop down window that appears and
                // not just over its scrollbar before we actually try to update anything
                // then if we are raise the Hover event for this comboBox
                if (!(xPos > this.Width - SCROLLBAR_WIDTH || xPos < 1 || oldYPos < 0 || oldYPos > this.ItemHeight * this.MaxDropDownItems))
                    HoverEventArgs e = new HoverEventArgs();
                    e.itemIndex = onScreenIndex;
                    // if scrollPos doesn't equal the nPos from our ScrollInfoStruct then
                    // the mousewheel was most likely used to scroll the drop down list
                    // while the mouse was inside it - this means we have to manually
                    // tell the drop down to repaint itself to update where it is hovering
                    // still posible to "outscroll" this method but it works better than
                    // without it present
                    if (scrollPos != si.nPos)
                        Cursor.Position = new Point(Cursor.Position.X + xFactor, Cursor.Position.Y);
                        xFactor = -xFactor;

                scrollPos = si.nPos;
            // Pass on our message
            base.WndProc(ref msg);

Would you be happy with a solution written in C#?

I have previously solved the problem of determining which item the mouse is over when a list is dropped down but it's not in  If you specifically want the solution in I can probably convert it over the weekend when I have some free time.

jake072Author Commented:
I could convert it myself...

I've been struggling with this for 2 days...  ANYTHING would be appreciated!!!


Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

jake072Author Commented:
Thanks Neil,

Does anyone happen to know how to set a tool tip for the dropdown of the combobox?


jake072Author Commented:
I have found a way to use a floating control to serve as the tooltip, thanks for your help Neil!

Glad you got the floating control to work!

Good luck!
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.