How to prevent other mouse buttons from interrupting MouseMove? - c#

If you place a panel in a new C# project and capture it's MouseMove event like this:
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
Console.WriteLine("e.X: {0}, e.Y: {1}", e.X, e.Y);
}
It tells you the client coordinates of the mouse while the left mouse button is held down, even if the cursor goes outside of the panel.
However, if you are holding down left mouse button in the container and then, while holding down left mouse button, click any other mouse button on your mouse, it no longer calls MouseMove while outside the bounds of the container.
Is there any way to change this? Thanks for reading.

1: If you are trying to get it to work only when the left button is down, try the following:
bool mouseDown = false;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (!mouseDown)
return;
Console.WriteLine("e.X: {0}, e.Y: {1}", e.X, e.Y);
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
mouseDown = true;
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
mouseDown = false;
}
2: Otherwise, if you want it to work when any mouse button is down, try the following:
int mouseDown = 0;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown == 0)
return;
Console.WriteLine("e.X: {0}, e.Y: {1}", e.X, e.Y);
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown++;
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown--;
}

In addition to Justin's solution will say that:
I think it's because, if during drag you go out of the panel right click out of the panel, forces panel to lose the focus, so control no more becomes an active one.
In case of when you're dragging mouse inside panel and click with right click inside panel, happens something like this.
I just captured with Spy++ windows explorer and did a test, so moved the mouse with LButton down and at some point without releasing it made a right click. And here is a result:
With arrows I sign the row where I clicked with right button, where WM_CAPTURECHANGED
message sent. This message according to documentation is:
Sent to the window that is losing the mouse capture.
Look on next line with arrow. The handle of the next window is 0, so there is no any window. So this means, like a simple command: You lost a capture on mouse.
Hope this helps.

Related

c# Can I turn EventArgs in to MouseEventArgs?

I think this is to do with casting:
First, I declare an event handler for my picturebox:
pictureBox1.MouseHover += new EventHandler(this.pictureBox1_MouseHover);
Next I'm trying to check whether the left mousebutton is held down with:
private void pictureBox1_MouseHover(object sender, EventArgs e)
{
if (e.Button == MouseButtons.Left)
{
/*some gibberish for when the left mouse button is held*/
}
}
But this doesn't work, because EventArgs is not MouseEventArgs
Can I Cast or somehow convert EventArgs e to be treated as MouseEventArgs so that the above code would work?
Can you turn an apple in an orange? No. Well, you can't just make an MouseEventArgs from an EventArgs instance.
In this case, your code doesn't make sense. You are trying to get the button of a hover event. Hovering is done without any button clicks. If you want to know the button pressed at time of hovering, you need to cache the MouseDown and MouseUp events first to register what button was clicked.
If you want to check if a mouse button is pressed while moving the mouse, then you should subscribe to PictureBox.MouseDown, PictureBox.MouseMove and PictureBox.MouseUp events if you want to record the mouse movement from the point you first pressed the button, while you're moving the mouse while still holding the button and when you release the button.
private void PictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//Handle mouse down logic here (press).
}
}
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//Handle mouse move logic here (hold).
}
}
private void PictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//Handle mouse up logic here (release).
}
}

Winforms custom cursor stops setting after a time

I have a form that contains a panel. The idea is that when the mouse is hovered over the panel it displays the OpenHand cursor. You can then drag the panel which causes the cursor to change to the Grab cursor. Upon mouse release the Grab cursor should change back to the OpenHand cursor.
Unfortunately, I'm having an issue that if I drag and release my panel (with the mouse within the bounds of the panel), eventually (usually on the second or third go) the Grab cursor will not change back into the OpenHand cursor.
This remains the case even when you move the mouse out of the panel and back in and try dragging and releasing.
Here is my Panel class:
public class MapPanel : Panel
{
private Point MouseDownLocation;
private Cursor OpenHand = new Cursor(Properties.Resources.hand.Handle);
private Cursor Grab = new Cursor(Properties.Resources.punch.Handle);
public MapPanel()
{
MouseDown += new MouseEventHandler(mapPanel_MouseDown);
MouseUp += new MouseEventHandler(mapPanel_MouseUp);
MouseMove += new MouseEventHandler(mapPanel_MouseMove);
}
private void mapPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Cursor = Grab;
MouseDownLocation = e.Location;
}
}
private void mapPanel_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Cursor = OpenHand;
}
}
private void mapPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Left = e.X + Left - MouseDownLocation.X;
Top = e.Y + Top - MouseDownLocation.Y;
}
}
}
Interestingly there are no issues if I don't include the MouseMove handler, however the Cursor = OpenHand; statement inside the MouseUp method does still get called with the MouseMove handler included. It just doesn't take effect.
Hopefully someone can shed some light on this. Any help would be very much appreciated!

How to stop mouse left button function on datagridview c#

Mouse left button should be stop select or click when i edit cell in datagridview. i don't know how to disable mouse left button in windows application.
you can manage the action in MouseClick event:
private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
// do something
}
}

Listbox events firing strangely

I'm confused. I am basically trying to tell when the user has clicked something in the listbox, held the button, and left the listbox. Here is a somewhat dumbed down version of what I am doing:
private bool itemHeld;
private void listOriginal_MouseDown(object sender, MouseEventArgs e)
{
itemHeld = true;
}
private void listOriginal_MouseUp(object sender, MouseEventArgs e)
{
itemHeld = false;
}
private void listOriginal_MouseLeave(object sender, EventArgs e)
{
if (itemHeld)
MessageBox.Show("OHH YEAH");
}
To me that seems like it should turn itemHeld true when you press the mousebutton, turn it false only if you lift it, and display ohh yeah if the value is true. If I break on the mouse down event to check the value, it is true and if I continue from there it displays the message. If I do not break, it does nothing. Is there something else at work here?
Edit:
Brief description: It would be difficult to explain what I am really trying to accomplish but imagine something almost like dragging a file off of a window. I need to simply be able to recognize when the user clicks inside of the listbox and then drags out of the listbox if that makes sense
You can not debug windows events by break point because when the Visual Studio get active to debug, the mouse leave event will be fired for the hovered control.
You can use Debug.WriteLine which writes information about the debug to the trace listeners.
private void button1_MouseLeave(object sender, EventArgs e)
{
Debug.WriteLine("Mouse leave");
}
private void button1_MouseEnter(object sender, EventArgs e)
{
Debug.WriteLine("Mouse enter");
}
private void button1_MouseHover(object sender, EventArgs e)
{
Debug.WriteLine("Mouse hover");
}
what about this?
private void listBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.X > listBox1.Width - 1 || e.Y > listBox1.Height - 1 || e.X < 0 || e.Y < 0)
{
Console.WriteLine("drag out");
}
else
Console.WriteLine("mouse move {0}/{1}", e.X, e.Y);
}
it uses the fact that the Control is not left before the mousebutton is released ... but be aware that the drag out part will occur more than once so you probably will want to have a flag set the first time ... and have that flag cleared on mouse up or leave
For every mouse click, your MouseDown event will fire AND your MouseUp event will fire, so the sequence of operations is equivalent to
itemHeld = true;
itemHeld = false;
if(itemHeld)
MessageBox.Show("yay");
If you press the mouse button on the listbox and move the cursor out without releasing the button, switching focus to another window (e.g. Visual Studio) is what triggers the MouseLeave event to fire. This is why you're seeing the message box pop up when you're debugging.
I'm not sure what you're trying to accomplish, so I can't recommend another solution.

How can I determine which mouse button raised the click event in WPF?

I have a button that I trigger OnClick whenever there is a click on that button. I would like to know which Mouse button clicked on that button?
When I use the Mouse.LeftButton or Mouse.RightButton, both tell me "realsed" which is their states after the click.
I just want to know which one clicked on my button. If I change EventArgs to MouseEventArgs, I receive errors.
XAML: <Button Name="myButton" Click="OnClick">
private void OnClick(object sender, EventArgs e)
{
//do certain thing.
}
You can cast like below:
MouseEventArgs myArgs = (MouseEventArgs) e;
And then get the information with:
if (myArgs.Button == System.Windows.Forms.MouseButtons.Left)
{
// do sth
}
The solution works in VS2013 and you do not have to use MouseClick event anymore ;)
If you're just using the Button's Click event, then the only mouse button that will fire it is the primary mouse button.
If you still need to know specifically whether it was the left or right button, then you can use the SystemInformation to obtain it.
void OnClick(object sender, RoutedEventArgs e)
{
if (SystemParameters.SwapButtons) // Or use SystemInformation.MouseButtonsSwapped
{
// It's the right button.
}
else
{
// It's the standard left button.
}
}
Edit: The WPF equivalent to SystemInformation is SystemParameters, which can be used instead. Though you can include System.Windows.Forms as a reference to obtain the SystemInformation without adversely effecting the application in any way.
You're right, Jose, it's with MouseClick event. But you must add a little delegate:
this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyMouseDouwn);
And use this method in your form:
private void MyMouseDouwn(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
this.Text = "Right";
if (e.Button == MouseButtons.Left)
this.Text = "Left";
}

Categories