Avoid Toolstripmenu close on items or Dropdownitem selected - c#

I have Toolstrip menu items. It is having two level of menu items. How to avoid close functionality of Toolstrip menu item when clicks on level 2 menu item and retains the previous one.
Example,

You're going to want to specify closing behaviour for the drop down to not close on item click. Try this:
toolStripDropDownButton1.DropDown.Closing += toolStripDropDownButton1_Closing;
private void toolStripDropDownButton1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
{
e.Cancel = true;
}
}

Related

WinForms ContextMenu stays open when MenuItem is clicked

So I have a form DataGridView and when I right click on the grid I want to display a context menu that has one menu item in it. The menu item will open a second form that will provide some configuration options for the DataGridView.
Now all of this works absolutely fine, the context menu displays correctly and the second form opens correctly and all of the functionality on that form works correctly.
The only issue is that the context menu will only close if I click anywhere other than the menu item. No matter how many times I click on the menu item the context menu does not close.
I have tried looking for work arounds but as far as I can tell there is no way to programatically close the context menu.
Any help would be greatly appreciated. Below are copies of the click events for opening the context menu and for the menu item click event.
private void DataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
DataGridView dgv = (DataGridView)sender;
if (dgv.CurrentCell == null)
{
return;
}
else
{
Rectangle r = dgv.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
Point p = new Point(r.X + e.X, r.Y + e.Y);
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add(new MenuItem("Item", Item_Click));
cm.Show(dgv, p);
}
}
}
private void Item_Click(object sender, EventArgs e)
{
new SecondForm().Show();
}
UPDATE:
I solved the issue by replacing the ContextMenu class with the ContextMenuStrip class, removing the MouseClick event handler and assigning the ContextMenuStrip object to DataGridView.ContextMenuStrip. It appears as though the ContextMenuStrip class deals with showing the menu when it's relevant control is right clicked, so if you add a click event handler to deal with opening the menu it will repeatedly try to render the menu making it flicker several times before it is eventually rendered
in your class add a private variable
private bool CloseMenu = true;
on mouse down of your Context Menu
private void Item_Click(object sender, EventArgs e)
{
CloseMenu = false;
new SecondForm().Show();
}
add context menu closing event
private void contextMenuStripMy_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
e.Cancel = !CloseMenu;
CloseMenu = true;
}
I found some workdaround on this problem after many trials.
Firstly, this is about ContextMenu and not ContextMenuStrip.
This is not perfect solution but it works good if you do not have other alternative solution.
Here is how.
Just Set Visiable = false for all MenuItems under the Context Menu.
Only one problem with this is that it shows small square around the mouse.
I think this small square is the empty context menu box.
However, this small square will be removed quickly if user clicks anywhere and if the context menu lose focus.
It is really small and not bothering.
In code, this will look something like this in case you have only one menu item.
if (cm != null)
{
if (cm.MenuItems.Count > 0) cm.MenuItems[0].Visible = false;
}
If you have multiple of items, then just loop through all menu items.
if (cm != null)
{
for(int i = 0; i < cm.MenuItems.Count ; i++)
cm.MenuItems[i].Visible = false;
}
Hope this helps.
It worked for my case.
So I did not have to swtich to ContextMenuStrip from ContextMenu.

Is there a way to stop a Menu from closing when you click on it?

We have a form in our program that allows a user to determine what a user can see when setting privileges, by using a menu bar. When a user clicks on an item, that item then is "selected" (gets a tick next to it). However, this also closes the menu.
Is there a way to stop this menu from closing (without affecting any other menu's in the program) when a user clicks on it? So far I have not found anything in the settings, and any _click methods are not affecting it either.
Listen the ToolStripDropDownClosingEventHandler present in ToolStripDropDown. To do this just access the ToolStripMenuItem.DropDown Property, and so, add a listener that will handle the Closing event. We just need to check if the mouse pointer it's inside of toolStrip rectangle and this can be done with this piece of code:
private void ListenToolStripMenuItems(IEnumerable<ToolStripMenuItem> menuItems)
{
// listen all menuItems
foreach (ToolStrip menuItem in menuItems)
menuItem.DropDown.Closing += OnToolStripDropDownClosing;
}
private void OnToolStripDropDownClosing(object sender, ToolStripDropDownClosingEventArgs e)
{
var tsdd = (ToolStripDropDown)sender;
// checking if mouse cursor is inside
Point p = tsdd.PointToClient(Control.MousePosition);
if (tsdd.DisplayRectangle.Contains(p))
e.Cancel = true; // cancel closing
}
This way the AutoClose still working and the toolStrip will close properly.
I'm a hack, but I would do this for each item you can click:
sampleNameToolStripMenuItem.ShowDropDown();
That way whenever you click something, it will also drop the menu down again right after.
I had a similar issue. The Items to be checked was a Level down in my case.
I solved it by adding a MouseEnter and MouseLeave Event to the ToolStripMenuItems that can be checked/unchecked.
In the MouseEnter I set AutoClose of both menuItems to false - in the MouseLeave I set it back to true.
Visualization of the issue I had
private void AddEventToToolStripMenuItems(IEnumerable<ToolStripMenuItem> menuItems)
{
// listen all menuItems
foreach (ToolStripMenuItem menuItem in menuItems)
{
menuItem.MouseEnter += OnToolStripMouseEnter;
menuItem.MouseLeave += OnToolStripMouseLeave;
}
}
private void OnToolStripMouseEnter(object sender, EventArgs e)
{
firstLevelTooStipMenuItem.DropDown.AutoClose = false;
secondLevelTooStipMenuItem.DropDown.AutoClose = false;
}
private void OnToolStripMouseLeave(object sender, EventArgs e)
{
firstLevelTooStipMenuItem.DropDown.AutoClose = true;
secondLevelTooStipMenuItem.DropDown.AutoClose = true;
}
Get the ToolStripMenuItem
Get the DropDown from ToolStripMenuItem
Set AutoClose as false
Ref:
https://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripmenuitem(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripdropdown(v=vs.110).aspx

Do not close ToolStripMenu on clicking in winforms

I work on a c# winform project that the main toolstripmenu have not to be hide after user clicks on its item, how can I do that?
Set the AutoClose property of the parent menu item to prevent the menu strip from closing.
To demonstrate:
ToolStripMenuItem file = new ToolStripMenuItem("File");
file.DropDown.AutoClose = false;
file.DropDownItems.Add("New");
file.DropDownItems.Add("Open");
file.DropDownItems.Add("Exit");
MenuStrip ms = new MenuStrip();
ms.Items.Add(file);
this.Controls.Add(ms);
Now the responsibility is on you to close the menu yourself:
file.DropDown.Close();
I found better answer on MSDN forum. Dropdown doesn't close on click, but closes in other cases:
DropDown.Closing += new ToolStripDropDownClosingEventHandler(DropDown_Closing);
...
private void DropDown_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
{
e.Cancel = true;
}
}

Right Click to select items in a ListBox

I'm trying to make a list of items that you can do several actions with by right-clicking and having a context menu come up. I've completed that, no problem whatsoever.
But I'd like to have it so that when you right click on a item, instead of leaving the current item selected, to select the item the mouse is over.
I've researched this and other related questions, and I've tried to use indexFromPoint (which I found through my research) but whenever I right click on a item, it always just clears the selected item and doesn't show the context menu, as I have it set so that it wont appear if there is no selected item.
Here is the code I'm currently using:
ListBox.SelectedIndex = ListBox.IndexFromPoint(Cursor.Position.X, Cursor.Position.Y);
Handle ListBox.MouseDown and select the item in there. Like this:
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
listBox1.SelectedIndex = listBox1.IndexFromPoint(e.X, e.Y);
}
this one is working...
this.ListBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.List_RightClick);
private void List_RightClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
int index = this.listBox.IndexFromPoint(e.Location);
if (index != ListBox.NoMatches)
{
listBox.Items[index];
}
}
}
Can also get same behaviour by setting a MouseRightButtonUp event on the whole listbox then:
private void AccountItemsT33_OnMouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
// If have selected an item via left click, then do a right click, need to disable that initial selection
AccountItemsT33.SelectedIndex = -1;
VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), (sender as ListBox)).OfType<ListBoxItem>().First().IsSelected = true;
}

Context menu related problem

suppose my context menu is associated with 3 label control. when i will right click on those label then context menu will appear. i want to capture from the context menu click event that on which label the context menu click event called. i tried but failed.
void MyContextMenu_Click(object sender, EventArgs e)
{
if (sender.GetType() == typeof(Label))
{
if (((Label)sender).Name.ToUpper() == "LBLACCOUNTREFERENCE")
{
Clipboard.Clear();
Clipboard.SetData(DataFormats.OemText, (object)((Label)sender).Text);
}
}
else
{
Clipboard.Clear();
Clipboard.SetData(DataFormats.OemText, (object)this.localJob.JobPart.OEReference);
}
}
please guide me.
The sender parameter specifies the menu item that was clicked.
You're looking for the SourceControl property, which gives you the control that opened the ContextMenuStrip.
Check contextMenu.SourceControl.Text.

Categories

Resources