I am trying to show a popup menu on my treeview when users right click - allowing them to choose context sensitive actions to apply against the selected node.
At the moment the user has to left click node and then right click to choose.
Is it possible to make a right click on a node select that node - and if so what is the best method to do this.
Both left and right clicks fire a click event and cause the selection to change. However, in certain circumstances (that I haven't yet bothered to trace down) the selection will change from the node that was right clicked to the originally selected node.
In order to make sure that the right click changes the selection, you can forcibly change the selected node by using the MouseDown event:
treeView.MouseDown += (sender, args) =>
treeView.SelectedNode = treeView.GetNodeAt(args.X, args.Y);
A little better, as one of the other posters pointed out, is to use the NodeMouseClick event:
treeView.NodeMouseClick += (sender, args) => treeView.SelectedNode = args.Node;
yes. Here is processing for NodeMouseClick event:
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
treeView1.SelectedNode = e.Node;
}
Drag a context menu strip onto the form then:
private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
// Display context menu for eg:
ContextMenu1.Show();
}
}
Related
I have an event that fires using the AfterSelect Event, and this works just fine, but I do not want this event to fire if the user either checks or unchecks the checkbox of this or any node in the tree. Alternatively, the event can fire, but then I need to know inside the event if it was fired as a result of a check or uncheck of the checkbox. I have tried using NodeMouseClick instead but I get the same unwanted result, and I have also tried removing the event handler using BeforeCheck and adding it back using AfterCheck, like so:
private void MyTree_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
this.MyTree.AfterSelect -= new System.Windows.Forms.TreeViewEventHandler(this.MyTree_AfterSelect);
}
private void MyTree_AfterCheck(object sender, TreeViewEventArgs e)
{
this.MyTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.MyTree_AfterSelect);
}
private void MyTree_AfterSelect(object sender, TreeViewEventArgs e)
{
ShowMyInfo(e.Node);
}
but the AfterSelect event still fires.
I cannot rely on AfterCheck because then it won't fire if you simply select the node. I also cannot rely on checking if e.Node.Selected == true, because the node might already be checked, and I want the event to fire if the node is in fact deliberately selected.
Is there any event handler I can use that will trigger only if a node is SELECTED, and not CHECKED or UNCHECKED, or any way I can detect if a node that's just been selected has been checked or unchecked.
Using Visual Studio 2019 with a C# WinForms .NET Framework application.
As #Jimi and #dr.null have pointed out, I am using the right event after all. AfterSelect will not fire just because you checked or unchecked the checkbox.
The problem that I had was that I have code that will select a node if you right click it (right clicking does not automatically select a node).
Old Code:
private void MyTree_MouseDown(object sender, MouseEventArgs e)
{
MyTree.SelectedNode = MyTree.GetNodeAt(e.X, e.Y);
}
New Code:
private void MyTree_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) MyTree.SelectedNode = MyTree.GetNodeAt(e.X, e.Y);
}
I was inadvertently firing off my own event because I did not check for which mouse button was clicked on the MouseDown event. Thank you for the help!
Why in every right click, the contextmenustrip pop up,how to enable it in a specify position by controlling the right click event??
Try to remove the default contextmenustrip and create a new one.
With HitTest on a control you can check if the clicked position is on a element
private void MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
if (dataGrid.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.ColumnHeader)
{
new ContextMenuStrip().Show(dataGrid, e.Location);
}
}
}
See: How do I correctly position a Context Menu when I right click a DataGridView's column header?
I want to capture the right click mouse event within the ToolStripDropDownItemClicked Event
private void toolStripDropDownButton1_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
Based on the right click, i display a contextmenu. So, I need to get both the item clicked and mouse click right.
You could use the MouseUp or MouseDown event it knows which button was pressed.
The sender object is the menu item that was clicked. Cast it to the correct type to access it's properties. If you're not sure about the type you could use as and then check if the resulting object is null.
void firstToolStripMenuItem_MouseUp(object sender, MouseEventArgs e)
{
var toolStripMenuItem = (ToolStripMenuItem)sender;
var nullIfOtherType = sender as ToolStripMenuItem;
var right = e.Button == System.Windows.Forms.MouseButtons.Right;
}
How to get a right click mouse event? Changing EventArgs to MouseEventArgs causes an error in Form1Designer?
I have a PictureBox.
If I right click the PictureBox, my ContextMenuStrip (right click menu) appears.
In that ContextMenuStrip is a ToolStripMenuItem (one of the options in the right click menu).
There is an event on the ToolStripMenuItem that handles what happens if that option is clicked.
We're starting from ToolStripMenuItem's "Clicked" function. I need to somehow get back to the PictureBox programmatically. From there, I can modify the PictureBox.
ToolStripMenuItem -> ContextMenuStrip -> PictureBox
How would I go about this?
If the click event handler for your menu item is named OnToolStripMenuItemClick, the following might be an approach to your problem:
private void OnToolStripMenuItemClick(object sender, EventArgs e)
{
var menuItem = sender as ToolStripMenuItem;
var contextMenu = menuItem.Parent as ContextMenuStrip;
var pictureBox = contextMenu.SourceControl;
}
Of course, don't forget to check for null when accessing properties after conversion with as.
I'm not sure that I really understood your problem, but I guess you want to let users can return to the picturebox when they want to cancel current operation by clicking the right button. In this case, you should not implement your work in click event, because right and left button both can trigger the click event, instead, you should process your work in the event "MouseUp", like this:
private void menuItemBack_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MessageBox.Show("back item is clicked");
}
else
{
MessageBox.Show("I will come back.");
//do your return things here.
}
}
I've just come across this same problem in C#, and the path to the value seems to be something like:
sender.Owner.SourceControl;
However, since sender, Owner and so on are generic classes, I had to cast everything as follows:
PictureBox pb = (PictureBox) ((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl;
Ugly, but it works.
I added a context menu (add, cancel) to tree view dynamically. Now I want to show the selected tree node value when I click on context menu item click.
How can I do that?
I assume you want to know which node was right-clicked when the context menu is opened?
To determine this you can handle the mousedown event on the treeview and ensure the node you right-clicked is selected before the context menu is displayed.
private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var node = treeView1.HitTest(e.X, e.Y).Node;
treeView1.SelectedNode = node;
}
}
In the ToolStripMenuItem's click handler you can check treeView1.SelectedNode, it will be null if the user right clicked the treeview outside a node.
private void addToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null) MessageBox.Show("Node selected: " + treeView1.SelectedNode.Text);
}
I assume you just need to know the text of the treenode? This code should do the job
string treeNodeText = this.treeView1.SelectedNode.Text;