Solved

ToolTip in Custom ComboBox DropDown

Posted on 2006-05-25
6
798 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 14

Author Comment

by:jake072
Comment Utility
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
Comment Utility
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
Comment Utility
Glad you got the floating control to work!

Good luck!
Neil
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

763 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

6 Experts available now in Live!

Get 1:1 Help Now