c# Can I turn EventArgs in to MouseEventArgs? - c#

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).
}
}

Related

WinForms ListBox Right-Click

I am trying to add a context menu to a listbox when you right click an item.
I am not even sure if the right click function with working properly.
Here is the code:
private void lstSource_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Console.WriteLine("Right Click");
}
}
Nothing prints to the console. Am I missing something?
Thanks.
Make sure you wire the event up (and the ListBox is enabled):
private void Form1_Load(object sender, EventArgs e)
{
listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
}
void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
MessageBox.Show("Right Click");
}
}
You can also have the designer wire up the event for you by selecting the ListBox and double-clicking on the MouseDown event in the Properties window (click on the lightning bolt).
Console.WriteLine() method wont display anything on GUI. Use MessageBox.Show("Right Click");
private void lstSource_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
MessageBox.Show("Right Click");
}
}
EDIT: Be sure that the handler is attached with MouseDown event or not.

How to prevent other mouse buttons from interrupting MouseMove?

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.

CellDoubleClick event doesnt work after addition of Drag&Drop

After I added drag & drop to a DataGridView, the CellDoubleClick event stopped working. In the CellMouseDown event I have the following code:
private void dataGridView2_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
var obj = dataGridView2.CurrentRow.DataBoundItem;
DoDragDrop(obj, DragDropEffects.Link);
}
How do I correct this to enable CellDoubleClick event?
Yes, that cannot work. Calling DoDragDrop() turns mouse control over to the Windows D+D logic, that's going to interfere with normal mouse handling. You need to delay starting the D+D until you see the user actually dragging. This ought to solve the problem:
Point dragStart;
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) {
if (e.Button == MouseButtons.Left) dragStart = e.Location;
}
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
var min = SystemInformation.DoubleClickSize;
if (Math.Abs(e.X - dragStart.X) >= min.Width ||
Math.Abs(e.Y - dragStart.Y) >= min.Height) {
// Call DoDragDrop
//...
}
}
}

System Tray notifyIcon won't accept left-click event

I'm creating a System-Tray only application. It's somewhat complicated to have the icon without a main form, but through previous topics on StackOverflow I've worked it out. The right-click works fine, I've linked in a context menu, etc.
I'm having problems with the left-click. As far as I can tell, the "notifyIcon1_Click" event isn't firing at all.
private void notifyIcon1_Click(object sender, EventArgs e)
{
Debug.WriteLine("Does it work here?");
if (e.Equals(MouseButtons.Left))
{
Debug.WriteLine("It worked!");
}
}
Neither of those debug lines are outputting, breakpoints in that event don't stop the program, etc.
Am I doing this incorrectly? What should my next step be? I'm coding this in C#, using Windows 7 if that matters at all for taskbar behavior.
If you want to determine if it's a left or right click, wire up the MouseClick, rather than click.
That way you get a signature like this:
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
//Do the awesome left clickness
else if (e.Button == MouseButtons.Right)
//Do the wickedy right clickness
else
//Some other button from the enum :)
}
If you want the click event of the Message/Balloon itself use
_notifyIcon.BalloonTipClicked += notifyIconBalloon_Click;
private void notifyIconBalloon_Click(object sender, EventArgs e)
{
// your code
}
private void NotifyIcon_Click(object sender, EventArgs e)
{
MouseEventArgs mouseEventArgs = (MouseEventArgs)e;
if (mouseEventArgs.Button == MouseButtons.Right && IsHandleCreated)
{
popupMenu1.ShowPopup(MousePosition);
return;
}
if (mouseEventArgs.Button == MouseButtons.Left && IsHandleCreated)
{
if (isWindowMinimized)
showWindow();
else
hideWindow();
}
}
The other answer is not clear that you need MouseClick event instead of Click.
notifyIcon.MouseClick += MyClickHandler;
Then your handler function will work fine.
void MyClickHandler(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Console.WriteLine("Left click!");
}
}

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