I have a button on a form and want to handle both left and right clicks.
I am handling the MouseClick event, but this is only raised on a left click.
Is this a problem somewhere in my code (a setting that I have missed) or the intended functionality?
If this is not possible to fix, what is the best workaround - to handle the MouseUp event?
The reason I would like to use MouseClick is so that double clicks are automatically recognised.
Thanks for any feedback.
Use MouseUp !!
private void button6_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MessageBox.Show("LEFT");
}
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
MessageBox.Show("RIGHT");
}
}
Its hard to answer without code but in general, it should work.
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MessageBox.Show("LEFT");
}
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
MessageBox.Show("RIGHT");
}
}
// EventHandler
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
Edit: There is a MouseDoubleClick Event you might want to use to recognize double clicks. Works both, for left and right musebuttons.
Apparently the answer to this is that OnClick does not handle right click events for Buttons. The solution was therefore to use MouseUp/MouseDown and check for double clicks/clicks where the mouse moves on/off halfway through manually.
Related
I have a button on a form and want to handle both left and right clicks.
I am handling the MouseClick event, but this is only raised on a left click.
Is this a problem somewhere in my code (a setting that I have missed) or the intended functionality?
If this is not possible to fix, what is the best workaround - to handle the MouseUp event?
The reason I would like to use MouseClick is so that double clicks are automatically recognised.
Thanks for any feedback.
Use MouseUp !!
private void button6_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MessageBox.Show("LEFT");
}
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
MessageBox.Show("RIGHT");
}
}
Its hard to answer without code but in general, it should work.
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MessageBox.Show("LEFT");
}
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
MessageBox.Show("RIGHT");
}
}
// EventHandler
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseClick);
Edit: There is a MouseDoubleClick Event you might want to use to recognize double clicks. Works both, for left and right musebuttons.
Apparently the answer to this is that OnClick does not handle right click events for Buttons. The solution was therefore to use MouseUp/MouseDown and check for double clicks/clicks where the mouse moves on/off halfway through manually.
I'm remaking windows Minesweeper (from XP) and something they had included was that if you click a number with as many flags as it's number with the left and right mouse button at the same time, it reveals every other hidden tile around that number.
I'm having a hard time telling when both the Left and Right mouse buttons are pressed at the exact same time... I'm using a pair of bools, one for each button with the OnMouseDown and OnMouseUp events but if the 2 buttons are clicked at the exact same time (or really close), then only one MouseDown event goes off and the other does not... If you click and hold one of the buttons then click and hold the other, the code works though.
Is there a better way to detect this kind of "dual" click?
Edit:
Alright, small story for why I messed this up (it worked all along).
I have a macbook pro running Windows 7. For those of you who don't know, the macbook pro has a single bar for a mouse button that normally left clicks, but if you place 2 fingers down it right clicks, so you can't do both (and no way to middle click). So I was building my app and sending it to my friend, he was telling me it wasn't working, so I posted this question. I finally decided to try it on my other laptop, a Dell XPS with 2 mouse buttons... Once it worked there I passed it along to other friends and they confirmed it worked. I don't know how my first friend messed it up, but moral of the story is don't buy anything Apple. At least that's the moral I got.
Create a class boolean variable for the left and right button defaulted to false. When the mouse down event fires set the variable to true and check if both are true. When the mouse up fires set the variable to false.
public bool m_right = false;
public bool m_left = false;
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
m_objGraphics.Clear(SystemColors.Control);
if (e.Button == MouseButtons.Left)
m_left = true;
if (e.Button == MouseButtons.Right)
m_right = true;
if (m_left == false || m_right == false) return;
//do something here
}
private void MainForm_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
m_left = false;
if (e.Button == MouseButtons.Right)
m_right = false;
}
Complete Code:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) leftPressed = true;
else if (e.Button == MouseButtons.Right) rightPressed = true;
if (leftPressed && rightPressed)
{
MessageBox.Show("Hello");
// note:
// the following are needed if you show a modal window on mousedown,
// the modal window somehow "eats" the mouseup event,
// hence not triggering the MouseUp event below
leftPressed = false;
rightPressed = false;
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) leftPressed = false;
else if (e.Button == MouseButtons.Right) rightPressed = false;
}
Another option is to use the static MouseButtons on the System.Windows.Forms.Control class
This will tell you which mouse buttons are currently pressed so that you can do something like the following:
((Control.MouseButtons & MouseButtons.Right) == MouseButtons.Right) &&
((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left)
You can also check out the MSDN example
I got the following code to work in my Click Event.
if ((Control.MouseButtons == MouseButtons.Right) || (Control.MouseButtons == MouseButtons.Left))
When only one mouse button is being pressed the "Control.MouseButton" assumes the value of "MouseButtons.None"
But when both the left and right mouse buttons are being pressed the "Control.MouseButton" assumes the value of either "MouseButtons.Right" or "MouseButtons.Left" according to which was pressed first / last (depending on how long time it was between the left and right button being pressed)
Try this,
Private Sub Form_Click(... , ByVal e As ystem.Windows.Forms.MouseEventArgs)
If e.Button = MouseButtons.Right And e.Button = MouseButtons.Left Then
MsgBox ('Right & Left code')
End If
Kind of an old question, but I came across this (coincidentally also while doing a Minesweeper clone) and felt it was missing something. If you want to have the two-button click but still catch regular single-button clicks as well, you can do the following:
private bool left_down;
private bool right_down;
private bool both_click;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
left_down = true;
if (right_down)
both_click = true;
}
if (e.Button == MouseButtons.Right)
{
right_down = true;
if (left_down)
both_click = true;
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (!right_down)
{
if (both_click)
//Do both-click stuff here
else
//Do left-click stuff here
both_click = false;
}
left_down = false;
}
if (e.Button == MouseButtons.Right)
{
if (!left_down)
{
if (both_click)
//Do both-click stuff here
else
//Do right-click stuff here
both_click = false;
}
right_down = false;
}
}
It moves the detection to the mouse-up rather than the mouse-down. It doesn't do anything until you release both buttons. This works almost exactly like the Windows 7 version of Minesweeper, except that the right button alone in the original operates on mouse-down. (I honestly prefer my version). There's a bit of redundancy in that the both-click case is called in two places depending on whether you release the left or right button first, but this should probably be a single-line function-call anyhow. Bonus: You can check the both_click flag from elsewhere in order to draw the hint-square around your cursor showing which squares will be revealed when you release the buttons.
I have a question.
I put a treeview control on my form and added some nodes.
public Form1()
{
InitializeComponent();
treeView1.Nodes.Add("root node #1");
treeView1.Nodes.Add("root node #2");
treeView1.Nodes.Add("root node #3");
treeView1.Nodes.Add("root node #4");
treeView1.Nodes.Add("root node #5");
}
I want to change standard right-click behavior. When I right-clicked on a tree Node then Treeview changed for a while selectedIndex. I don't want it. How can I fix standard behavior ?
In ideal, it would be: right click on a treenode text --> context menu appears, right click anywhere outside treenode text --> (absolutely) nothing happens.
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
// put your logic here like
// ContextMenu1.Show();
}
}
Alex,
Try this. The BeforeSelect handlers event args Cancel is tied to the fact that the right mouse is down. This suppresses the firing of the SelectedIndex changed. The MouseDown tracks if the right mouse is depressed and displays the context menu. The display is safe to move to MouseUp instead of MouseDown. The MouseUp clears the flag indicating that the RightMouse button is depressed.
All of this information on how I did this is available on MSDN. The trick is actually reading the names of all of the events -- Yes I know there are a lot -- then making a list of the "interesting ones" in your case you named SelectedIndex changing, and Mouse clicks. That immediately limits the event names you should read in detail on... If you want the text to not highlight while you're right clicking... well that's a different matter entirely and I caution you against it as it's valuable user feedback.
bool isRBut = false;
private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
isRBut = e.Button == MouseButtons.Right;
if (isRBut)
{
TreeViewHitTestInfo hti =treeView1.HitTest(e.Location);
if (hti.Location == TreeViewHitTestLocations.Label)
contextMenuStrip1.Show(treeView1, new Point(hti.Node.Bounds.Left, hti.Node.Bounds.Bottom));
}
}
private void treeView1_MouseUp(object sender, MouseEventArgs e)
{
isRBut = e.Button == MouseButtons.Right;
}
private void treeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e)
{
e.Cancel = isRBut;
}
Additionally, here's a bit of human language trivia for you. Hopefully this will help you in the future. Phrases such as "No, no, no" are interpreted by native English speakers as very rude. Just do your best to list the behavior you see, and the behavior you want. Even if people misunderstand stick to the facts only and leave out the obvious signs of frustration. This will help you get what you're after. As well on SO if someone has a habit of not accepting answers many members here will have a habit of not providing future answers to such members.
Override the MouseClick event, and in the event check if the click was right click
private void treeView1_MouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
//Do something
}
}
You need to handle the NodeMouseClick event and check the right mouse button was clicked:
treeView1.NodeMouseClick += (o, e) => {
if(e.Button == MouseButtons.Right)
{
//show menu...
}
};
I want to create a card playing game. I the use mousemove event to drag cards through the window. The problem is if I move the mouse over another card, it is stuck because the card underneath the mouse cursor gets the mouse events, so that the MouseMove event of the window isn't fired.
This is what I do:
private void RommeeGUI_MouseMove(object sender, MouseEventArgs e)
{
if (handkarte != null)
{
handkarte.Location = this.PointToClient(Cursor.Position);
}
}
I tried the following, but there was no difference:
SetStyle(ControlStyles.UserMouse,true);
SetStyle(ControlStyles.EnableNotifyMessage, true);
Iam looking for a way to implement an application-global event-handler or a way to implement so called event-bubbling. At least I want to make the mouse ignore certain controls.
In order to do this you will need to keep track of a few things in your code:
On which card the mouse is pointing
when the mouse button is pressed;
this is the card that you want to
move (use the MouseDown event)
Move the the card when the mouse is moved
Stop moving the card when the mouse button is released (use the
MouseUp event)
In order to just move around controls, there is no need to actually capture the mouse.
A quick example (using Panel controls as "cards"):
Panel _currentlyMovingCard = null;
Point _moveOrigin = Point.Empty;
private void Card_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_currentlyMovingCard = (Panel)sender;
_moveOrigin = e.Location;
}
}
private void Card_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _currentlyMovingCard != null)
{
// move the _currentlyMovingCard control
_currentlyMovingCard.Location = new Point(
_currentlyMovingCard.Left - _moveOrigin.X + e.X,
_currentlyMovingCard.Top - _moveOrigin.Y + e.Y);
}
}
private void Card_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _currentlyMovingCard != null)
{
_currentlyMovingCard = null;
}
}
What you could do, is send the MouseDown event to the event.function you want to call.
Say you got a "Label" ontop of a "Card", but you wan't to "go-through" it:
private void Label_MouseDown( object sender, MouseEventArgs)
{
// Send this event down the line!
Card_MouseDown(sender, e); // Call the card's MouseDown event function
}
Now the appropriate event-function is called, even though the bothersome label was clicked.
Normally you do this by, before capturing the mouse, seeing if anybody else has it...
I have a ComboBox that is a simple drop down style. I wanted to open a new window when the user right clicks on an item in the list, but am having trouble getting it to detect a right click has occurred.
My code:
private void cmbCardList_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right && cmbCardList.SelectedIndex != -1)
{
frmViewCard vc = new frmViewCard();
vc.updateCardDisplay(cmbCardList.SelectedItem);
vc.Show();
}
}
If I change e.Button == MouseButtons.Left the whole thing fires off just fine. Any way I can get this working as I intend?
I'm afraid that will not be posible unless you do some serious hacking.
This article will explain.
Quoted for you:
Individual Controls
The following controls do not conform to the standard mouse click event behavior:
Button, CheckBox, ComboBox, and RadioButton controls
Left click: Click, MouseClick
Right click: No click events raised
Left double-click: Click, MouseClick;
Click, MouseClick
Right double-click: No click events
raised
As an epitaph to this question, you can make this work using normal .NET functionality; you just have to go a little deeper into the event call stack. Instead of handling the MouseClick event, handle the MouseDown event. I had to do something similar recently, and I simply overrode the OnMouseDown method instead of attaching a handler. But, a handler should work too. Here's the code:
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Right && !HandlingRightClick)
{
HandlingRightClick = true;
if (!cmsRightClickMenu.Visible)
cmsRightClickMenu.Show(this, e.Location);
else cmsRightClickMenu.Hide();
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
HandlingRightClick = false;
base.OnMouseUp(e);
}
private bool HandlingRightClick { get; set; }
The HandlingRightClick property is to prevent multiple triggers of the OnMouseDown logic; the UI will send multiple MouseDown messages, which can interfere with hiding the right-click menu. To prevent this, I only perform the logic once on the first MouseDown trigger (the logic's simple enough that I don't care if two invocations happen to race, but you might), then ignore any other MouseDown triggers until a MouseUp occurs. It's not perfect, but this'll do what you need it to.
You can use the Opening event of ContextMenuStrip to handle right click event.
var chk = new CheckBox();
chk.ContextMenuStrip = cmsNone;
private void cmsNone_Opening(object sender, CancelEventArgs e)
{
e.Cancel = true;
var cms = (ContextMenuStrip)sender;
var chk = cms.SourceControl;
//do your stuff
}