I have some code:
_Item.MouseDown += new MouseEventHandler(delegate(Object o, MouseEventArgs a)
{
SrcRoot = BuilderParametresPath[_index].pngPath;
DstRoot = BuilderParametresPath[_index].scenesPath;
TextsXmlFileName = BuilderParametresPath[_index].textsPath;
NavigationSystemPath = BuilderParametresPath[_index].hintPath;
LevelsXmlFileName = BuilderParametresPath[_index].LevelsFilePath;
if (a.Button == MouseButtons.Right)
{
ContextMenuStrip docMenu = new ContextMenuStrip();
ToolStripMenuItem deleteLabel = new ToolStripMenuItem();
deleteLabel.Text = "Удалить";
docMenu.Items.AddRange(new ToolStripMenuItem[] { deleteLabel });
ocMenu.Show(MousePosition);
}
});
But it does not work, because pressing the right button does not work out. What can be done?
Add a contextMenuStrip control to the form.
Now enter some menu items in the menu strip.
Click the target control which may be button/textbox/form and go to properties and in the properties select ContextMenuStrip and set the required contextMenuStrip control.
Then the context menu strip for the target control will appear when you right click to the targetead control.
Related
I have a C# Win Form.
Main Menu Form have
Button A
Button B
Button C
Button Setup
Each Button will open a new win form.
After clicking Setup Button, It will open a Setup form.
This form will use a datagridview to list out all the button in Main Menu except Setup button.
Admin can click the check box to select which button to enable in the Main Menu
Anyone know how to achieve this implementation
part of my code in Setup form
foreach (Button button in ????.Controls.OfType<Button>())
{
if (!button.Text.Contains("Setup"))
{
int index = dgvCheckbox.Rows.Add();
dgvCheckbox.Rows[index].Cells["Selected"].Value = 0;
dgvCheckbox.Rows[index].Cells["Button"].Value = button.Text;
}
}
if I use
MainMenu mainMenu = new MainMenu
foreach (Button button in mainMenu.Controls.OfType<Button>())
will have problem because Main Menu is already open
I create CheckBox (instead of menu) before show form so you can fill menu in the same way (this code is on main form):
private void buttonSetup_Click(object sender, EventArgs e) {
using (var adminForm = new AdminForm()) {
foreach (var button in Controls.OfType<Button>().Where(bt => !bt.Text.Contains("Setup"))) {
adminForm.Controls.Add(new CheckBox {
Text = button.Text,
Location = button.Location
});
}
adminForm.ShowDialog();
}
}
This code is in the form1 constructor:
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Save Rectangle");
cm.MenuItems.Add("Reset Rectangle");
cm.MenuItems.Add("View Rectangle Information");
listBoxSnap.ContextMenu = cm;
Now what it does, is that any item or area I right click on in the ListBox, it will show the menu. But I want that it will make right click and show the menu only if I make right click on the selected item I'm on now. When I run my program, the first item is selected automatically:
if (this.listBoxSnap.Items.Count > 0)
this.listBoxSnap.SetSelected(0, true);
listBoxSnap.Select();
I want that if I clicked the mouse left button to select another item, or moved the keyes up down to select an item, then the menu right click will be available(enabled) for this item only. And if I make right click on any other area in the listBox don't show the menu.
Show the menu only if I put the mouse cursor on the current selected item.
Same as when in windows when I mark text and right click on the it, it will show me a menu, and if I right click on other text that is not marked, it will show me a different menu.
EDIT:
This is working.
In top of form1:
ContextMenu cm;
In form1 constructor:
cm = new ContextMenu();
cm.MenuItems.Add("Save Rectangle");
cm.MenuItems.Add("Reset Rectangle");
cm.MenuItems.Add("View Rectangle Information");
And listBox mouse down event:
private void listBoxSnap_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var item = listBoxSnap.IndexFromPoint(e.Location);
if (item >= 0)
{
listBoxSnap.SelectedIndex = item;
cm.Show(listBoxSnap, e.Location);
}
}
}
Try like this
private void listBoxSnap_MouseUp(object sender, MouseEventArgs e)
{
if (listBoxSnap.SelectedIndex == -1 || e.Button != MouseButtons.Right)
return;
Rectangle r = listBoxSnap.GetItemRectangle(listBoxSnap.SelectedIndex);
if (r.Contains(e.Location))
{
cm.Show(listBoxSnap, e.Location);
}
}
![enter image description here][1]I am trying to add a combobox to ContextMenu on a datagrid when a user right clicks, the menu will pop up. It should show exit and assign to bankID menu options where the bank ID is a combobox dropdown. I did some online search but couldn't find anything close which makes me wonder, it is even possible to do that. I created a mockup image of what I'm trying to do with some code. If anyone has done something similar and share with me, I would really appreciate it. Thanks.
private ContextMenu menuOpp = new ContextMenu();
private ComboBox cmbAssign = new ComboBox();
private int currentMouseOverRow;
private void dataGridView2_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
menuOpp.Name = "Exit";
menuOpp.MenuItems.Add("Exit", new EventHandler(menuItem_Click));
cmbAssign.Items.Add("assign");
dataGridView2.ContextMenu = menuOpp;
currentMouseOverRow = dataGridView2.HitTest(e.X, e.Y).RowIndex;
menuOpp.Show(dataGridView2, new Point(e.X, e.Y));
}
}
I was able to resolve this myself. I created a ContextMenuStrip, added a MenuItem with sub ComboBox item, populated the ComboBox on ToolStripMenuItem Click event. Then assigned ContextMenuStrip object to its ContextMenuStrip property. After assigning the ContextMenuStrip object to a control, the contextual menu displayed as user right click.
private void InitializeComponent()
{
System.Windows.Forms.ContextMenuStrip Context =
new System.Windows.Forms.ContextMenuStrip();
ToolStripMenuItem mnuAssign = new ToolStripMenuItem("Assign");
Context.Items.Add(mnuAssign);
ContextMenuStrip = context;
}
I'm creating a ToolStripMenu shown below that is supposed to allow the user to interact with the items "XML" and "Non XML" as though they are regular check boxes on a form. However, when one item is checked/unchecked the menu closes. How can I allow an item to be checked/unchecked without closing the menu? Or is there a different standard method of achieving the same behavior?
So what I want is to be able to click on "Non XML", show a check box and leave the menu open.
The idea is that the last menu item will be "Done" and when it's clicked the "G2S" sub items will remain open but the "Display" sub items ( XML, Non XML ) will close.
Any ideas?
Note: I am aware that this is likely not the best user interface design. I'd like to know however how this could be accomplished just to gain some technical knowledge about handling menus.
Interesting concept is described in this thread on Stackoverflow:
Here is the essence of the accepted answer:
ParentMenu.DropDown.AutoClose = false;
It does exactly what you are asking for - prevent menu from closing when subitem is clicked.
Here's a useful extension that requires user to click outside of menu item + dropdowns to close.
public static void KeepOpenOnDropdownCheck (this ToolStripMenuItem ctl)
{
foreach (var item in ctl.DropDownItems.OfType<ToolStripMenuItem>())
{
item.MouseEnter += (o, e) => ctl.DropDown.AutoClose = false;
item.MouseLeave += (o, e) => ctl.DropDown.AutoClose = true;
}
}
Posted in case somebody finds it helpful.
Instead of trying to do exactly what I had originally intended, I've come up with the following:
1- Use a ContextMenuStrip
2- When the user clicks on the ToolStripMenu item I display the ContextMenuStrip at a location near the menu item as shown below: ( note the positioning still needs adjusting )
To get this working I build the ContextMenuStrip in code at run-time so that the items in the ContextMenuStrip can be build dynamically based on the situation.
Code snippets:
Show the ContextMenuStrip when the menu item is clicked:
private void filterToolStripMenuItem_Click(object sender, EventArgs e)
{
contextMenuStrip1.Show(this, 180, 20);
}
Build the ContextMenuStrip:
if (protInfo.Name == "QCOM" )
{
BroadCast = new CheckBox();
BroadCast.Text = "Date/Time Broadcast";
BroadCast.Checked = FlagSet(CurrentFilter, (Byte)Filter.DateTimeBC);
ToolStripControlHost Ch1 = new ToolStripControlHost(BroadCast);
GenPoll = new CheckBox();
GenPoll.Text = "Status Poll";
GenPoll.Checked = FlagSet(CurrentFilter, (Byte)Filter.GenStatusPoll);
ToolStripControlHost Ch2 = new ToolStripControlHost(GenPoll);
GenPollResp = new CheckBox();
GenPollResp.Text = "Status Poll Response";
GenPollResp.Checked = FlagSet(CurrentFilter, (Byte)Filter.GenStatusResponse);
ToolStripControlHost Ch3 = new ToolStripControlHost(GenPollResp);
Button btnDone = new Button();
btnDone.Text = "Done";
ToolStripControlHost Ch4 = new ToolStripControlHost(btnDone);
btnDone.Click += new EventHandler(btnDone_Click);
contextMenuStrip1.Items.Clear();
contextMenuStrip1.Items.Add(Ch1);
contextMenuStrip1.Items.Add(Ch2);
contextMenuStrip1.Items.Add(Ch3);
contextMenuStrip1.Items.Add(Ch4);
contextMenuStrip1.Enabled = true;
filterToolStripMenuItem.Enabled = true;
}
else
{
filterToolStripMenuItem.Enabled = false;
}
This may not be the best user interface design, but it seems to work.
The original solution will work with the use of mouse events.
On mouse enter event:
parent.dropdown.autoclose = false;
on mouse leave event:
parent.dropdown.autoclose = true;
The only catch is if the user access the menu items by other means than a mouse.
I used a combination of Neolisk's and Chimera's answers to allow deletion of multiple leaf items from a treeview. My solution is below
Note: the following Items created at design time are used:
TreePromotions (TreeView)
menuVendorSection (Context Menu Strip)
removeMultipleItemsToolStripMenuItem (DropDown of menuVendorSection)
private void removeMultipleItemsToolStripMenuItem_MouseHover(object sender, EventArgs e)
{
removeMultipleItemsToolStripMenuItem.DropDownItems.Clear();
ToolStripMenuItem detailMenuItem;
TreeNode vendorSectionNode = treePromotions.SelectedNode;
for (int vsn = 0; vsn < vendorSectionNode.Nodes.Count; vsn++)
{
//add checkbox item
detailMenuItem = new ToolStripMenuItem(vendorSectionNode.Nodes[vsn].Text);
detailMenuItem.Tag = vendorSectionNode.Nodes[vsn].Tag;
detailMenuItem.CheckOnClick = true;
removeMultipleItemsToolStripMenuItem.DropDownItems.Add(detailMenuItem);
}
//add action buttons
Button buttonDeleteMultiple = new Button();
buttonDeleteMultiple.Text = "Remove Checked Items";
ToolStripControlHost buttonHost = new ToolStripControlHost(buttonDeleteMultiple);
buttonDeleteMultiple.Click += new EventHandler(buttonDeleteMultiple_Click);
removeMultipleItemsToolStripMenuItem.DropDownItems.Add(buttonHost);
Button buttonCancelMultipleDelete = new Button();
buttonCancelMultipleDelete.Text = "CANCEL";
buttonHost = new ToolStripControlHost(buttonCancelMultipleDelete);
buttonCancelMultipleDelete.Click += new EventHandler(buttonCancelMultipleDelete_Click);
removeMultipleItemsToolStripMenuItem.DropDownItems.Add(buttonHost);
removeMultipleItemsToolStripMenuItem.DropDown.AutoClose = false;
menuVendorSection.AutoClose = false;
}
private void buttonDeleteMultiple_Click(object sender, EventArgs e)
{
//delete items
for (int dmi = 0; dmi < removeAllItemsToolStripMenuItem.DropDownItems.Count - 2; dmi++) //do not include buttons
{
((Detail)removeAllItemsToolStripMenuItem.DropDownItems[dmi].Tag).Delete(); //deletes item from database
}
//rebuild leaf
treePromotions.SelectedNode.Nodes.Clear();
addItemNodes(treePromotions.SelectedNode); //builds leaf nodes from database
//close menus
removeMultipleItemsToolStripMenuItem.DropDown.Close();
menuVendorSection.AutoClose = true;
menuVendorSection.Close();
}
private void buttonCancelMultipleDelete_Click(object sender, EventArgs e)
{
//just close menus
removeMultipleItemsToolStripMenuItem.DropDown.Close();
menuVendorSection.AutoClose = true;
menuVendorSection.Close();
}
If someone is still interested, here is a vb solution:
1) For the parent tool strip menu item, add the following handler in the form's constructor:
AddHandler ParentTSMI.DropDown.Closing, AddressOf onDropDownClosing
2) The handler:
Private Sub onDropDownClosing(sender As Object, e As ToolStripDropDownClosingEventArgs)
If e.CloseReason = ToolStripDropDownCloseReason.ItemClicked Then
e.Cancel = True
End If
End Sub
That's it all.
Don't forget to remove the handler (RemoveHandler) when you close the form.
I've got a TreeView, containing a number of levels of TreeViewItems.
I would like to add a context menu to only one level of items in the TreeView. However, my code produces a result whereby every single item in the TreeView has a context menu.
This is my code:
//.... foreach item in this level....
{
ContextMenu cmDatabase = new ContextMenu();
MenuItem menuItem = new MenuItem();
menuItem.Header = "Close Connection";
Image imgMenuIcon = new Image();
imgMenuIcon.Source = new BitmapImage(new Uri("icon.png"));
menuItem.Icon = imgMenuIcon;
cmDatabase.Items.Add(menuItem);
treeViewItem.ContextMenu = cmDatabase;
}
I've also tried manually setting all the other TreeViewItems' contextMenu property to null. No luck though. Any ideas?
The TreeView has a ContextMenuOpening event. Set the Handled property of the event handler argument e to true depending on the tree level. This will discard the context menu.
private void treeView1_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
e.Handled = <tree level does not require a context menu>;
}
If you have a TextBlock for your TreeViewItem, you can attach the ContextMenu onto that instead.
Textblock header = "TreeViewItem Text";
header.ContextMenu = cmDataBase;
treeViewItem.Header = header;
Also, for your other question that I answered, but you deleted before I hit Save. :P I'd put the right-click as an event (also on the header).
header.MouseRightButtonDown += new MousebuttonEventHandler(rightClickSelection);
private void rightclickSelection(object sender, MouseButtonEventArgs e) {
TreeViewItem clickedParent = (sender as TextBlock).Parent as TreeViewItem;
clickedParent.IsSelected = true;
clickedParent.UpdateLayout();
}