Solved

ToolTip in Custom ComboBox DropDown

Posted on 2006-05-25
6
809 Views
Last Modified: 2007-12-19
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
Comment
Question by:jake072
  • 3
  • 3
6 Comments
 
LVL 6

Expert Comment

by:neilprice
ID: 16770206
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
 
LVL 14

Author Comment

by:jake072
ID: 16770213
I could convert it myself...

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

Thanks!

Jake
0
 
LVL 6

Accepted Solution

by:
neilprice earned 500 total points
ID: 16770630
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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 14

Author Comment

by:jake072
ID: 16770811
Thanks Neil,

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

Thanks,

Jake
0
 
LVL 14

Author Comment

by:jake072
ID: 16771740
I have found a way to use a floating control to serve as the tooltip, thanks for your help Neil!

Jake
0
 
LVL 6

Expert Comment

by:neilprice
ID: 16771764
Glad you got the floating control to work!

Good luck!
Neil
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now