Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 840
  • Last Modified:

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: http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21731781.html

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

Thanks,

Jake
0
jake072
Asked:
jake072
  • 3
  • 3
1 Solution
 
neilpriceCommented:
Jake,

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 vb.net.  If you specifically want the solution in vb.net I can probably convert it over the weekend when I have some free time.

Neil
0
 
jake072Author Commented:
I could convert it myself...

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

Thanks!

Jake
0
 
neilpriceCommented:
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!

Neil

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
        {
            get
            {
                return _itemIndex;
            }
            set
            {
                _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
        [StructLayout(LayoutKind.Sequential)]
        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;
                    onScreenIndex++;
                }

                //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;
                    OnHover(e);
                    // 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);
        }
    }
}
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jake072Author Commented:
Thanks Neil,

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

Thanks,

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

Jake
0
 
neilpriceCommented:
Glad you got the floating control to work!

Good luck!
Neil
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now