submenu item dropdown on mouse over the parent item

1 Answer 295 Views
Menu
Patgat
Top achievements
Rank 2
Iron
Iron
Iron
Patgat asked on 29 Aug 2022, 11:25 AM

Dear support,

I have a naive question regarding dropdown menu.

I have created a standard Rad MenuBar with four standard menuItems. Some of these menu items will contains multiple sub-menu items and I would like to automatically have a dropdown behaviour when the user pass the mouse hover the corresponding parent menu item.

Is this possible and how ?

Many thanks

1 Answer, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 30 Aug 2022, 01:29 PM

Hi, Patrick,

If you want to automatically open the submenu on mouse hovering, you can use the following approach:

        public RadForm1()
        {
            InitializeComponent();
            for (int i = 0; i < 5; i++)
            {
                RadMenuItem item = new RadMenuItem("Item" + i);
                item.MouseHover += MenuItem_MouseHover;
                this.radMenu1.Items.Add(item);
                for (int j = 0; j < 3; j++)
                {
                    RadMenuItem subItem = new RadMenuItem("SubItem" + i);
                    subItem.MouseHover += MenuItem_MouseHover;
                    item.Items.Add(subItem);
                    for (int k = 0; k < 3; k++)
                    {
                        RadMenuItem grandChildItem = new RadMenuItem("GrandChildItem" + i);
                        subItem.Items.Add(grandChildItem);
                    }
                }
            }
        }

        private void MenuItem_MouseHover(object sender, EventArgs e)
        {
            RadMenuItem item = sender as RadMenuItem;
            if (item != null && item.Items.Count > 0)
            {
                item.DropDown.Show();
            }
        }

I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Patgat
Top achievements
Rank 2
Iron
Iron
Iron
commented on 30 Aug 2022, 02:09 PM

Hi Dess,

thanks for this solution which seems much nicer than the one I had devised. However, both seems to have some side effects.

Here is the way I did it previously (quite clumsy unfortunately) by computing the position of the mouse wrt the menu buttons :


    private void radMenu1_MouseHover(object sender, EventArgs e)
    {
        Point p = Cursor.Position;
        Point r = radMenu1.PointToClient(p);

        Point pt = new(0, 0);
        foreach (RadMenuItem rm in radMenu1.Items)
        {
            if (rm.Name == "rmiMAJDonnees") break;
            pt.X += rm.Size.Width;
        }
        Size s = radMenu1.Items["rmiMAJDonnees"].Size;

        if (r.X > pt.X && r.X < pt.X + s.Width && r.Y > 0 && r.Y < s.Height)
        {
            foreach (RadMenuItem ri in radMenu1.Items)
            {
                if (ri.Text == "MAJ Données")
                {
                    ri.ShowChildItems();
                }
            }
        }
   }

The main side effect of this is that if once the childItems are displayed, they stay displayed if the mouse pointer leave them by simply going down to the user window. The mouse need to go back to some other menu place to close the submenu list.

Therefore I have tried your solution, assuming that all the code outside the mouse_hover handler was for the example purpose, I simply replaced my code by yours in the mouse hover routine (as my menu entries are setup at design time).

The result is quite strange. Depending on were I clicked previously in the user window or in the menu various entries, the dropdown occurs or not.

Also in both case, could this be because the mousehover event is not always fired ?

Do I interpret wrongly your solution ?

Thanks for your patience.

Dess | Tech Support Engineer, Principal
Telerik team
commented on 31 Aug 2022, 11:21 AM

Hi, Patrick,

It is recommended to traverse the RadMenu.Items collection recursively and subscribe to the MouseHover event for each RadMenuItem. Please note that the MouseHover event is expected to be fired when the mouse stays for a little bit over the item. If you want to show the popup immediately after the mouse cursor is placed over the menu item, you can use MouseEnter and MouseLeave event for showing and hiding the popup respectively. 

        public RadForm1()
        {
            InitializeComponent();
            for (int i = 0; i < 5; i++)
            {
                RadMenuItem item = new RadMenuItem("Item" + i);
                item.MouseEnter += Item_MouseEnter;
                item.MouseLeave += Item_MouseLeave; 
                this.radMenu1.Items.Add(item);
                for (int j = 0; j < 3; j++)
                {
                    RadMenuItem subItem = new RadMenuItem("SubItem" + i); 
                    subItem.MouseEnter += Item_MouseEnter;
                    subItem.MouseLeave += Item_MouseLeave;
                    item.Items.Add(subItem);
                    for (int k = 0; k < 3; k++)
                    {
                        RadMenuItem grandChildItem = new RadMenuItem("GrandChildItem" + i);
                        subItem.Items.Add(grandChildItem);
                    }
                }
            }
        }

        Timer t;
        RadMenuItem lastHovered = null;
        private void Item_MouseLeave(object sender, EventArgs e)
        {
            RadMenuItem item = sender as RadMenuItem;
            if (item != null && item.Items.Count > 0)
            {
                lastHovered = item;
                t = new Timer();
                t.Interval = 1000;
                t.Tick += T_Tick;
                t.Start(); 
            }
        }

        private void T_Tick(object sender, EventArgs e)
        {
            t.Stop();
            if (lastHovered!=null && (lastHovered.OwnerControl!= this.radMenu1&&lastHovered.OwnerControl != lastHovered.DropDown))
            {
                lastHovered.DropDown.ClosePopup(RadPopupCloseReason.CloseCalled); 
            }
        }

        private void Item_MouseEnter(object sender, EventArgs e)
        {
            RadMenuItem item = sender as RadMenuItem;
            if (item != null && item.Items.Count > 0)
            {
                item.DropDown.Show();
            }
        }

Note that this is just a  sample approach and it may not meet all of your requirements. Feel free to modify and extend it in a way which suits your requirements best.

Tags
Menu
Asked by
Patgat
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or