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
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/.
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.
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.