wpf canvas double click - c#

I am trying to fetch a double click from the user on a canvas. I am using the previewmousedown event for this, but it isn't working properly.
The function is as following:
void DrawCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
/* Check if it is a double click */
if(e.ChangedButton == MouseButton.Left && e.ClickCount == 2)
{
//do double click actions
}
else
{
//do single click actions
}
e.Handled = true;
}
I have tried to move it to the previewmouseup function as well, but the clickcount stays on 1.
Anyone an idea why the clickcount doesn't go up?

Instead of using PreviewMouseLeftButtonDown Event, use MouseLeftButtonDownEvent to overcome this Problem.

Related

Distinguishing between Click and DoubleClick events in C#

I currently have a NotifyIcon as part of a Windows Form application. I would like to have the form show/hide on a double click of the icon and show a balloon tip when single clicked. I have the two functionalities working separately, but I can't find a way to have the app distinguish between a single click and double click. Right now, it treats a double click as two clicks.
Is there a way to block the single click event if there is a second click detected?
Unfortunately the suggested handling of MouseClick event doesn't work for NotifyIcon class - in my tests e.MouseClicks is always 0, which also can be seen from the reference source.
The relatively simple way I see is to delay the processing of the Click event by using a form level flag, async handler and Task.Delay :
bool clicked;
private async void OnNotifyIconClick(object sender, EventArgs e)
{
if (clicked) return;
clicked = true;
await Task.Delay(SystemInformation.DoubleClickTime);
if (!clicked) return;
clicked = false;
// Process Click...
}
private void OnNotifyIconDoubleClick(object sender, EventArgs e)
{
clicked = false;
// Process Double Click...
}
The only drawback is that in my environment the processing of the Click is delayed by half second (DoubleClickTime is 500 ms).
There are 2 different kinds of events.
Click/DoubleClick
MouseClick / MouseDoubleClick
The first 2 only pass in EventArgs whereas the second pass in a MouseEventArgs which will likely allow you additional information to determine whether or not the event is a double click.
so you could do something like;
obj.MouseClick+= MouseClick;
obj.MouseDoubleClick += MouseClick;
// some stuff
private void MouseClick(object sender, MouseEventArgs e)
{
if(e.Clicks == 2) { // handle double click }
}
It is enough to register a Click event and then handle single and double clicks from it.
int clickCount;
async void NotifyIcon_Click( object sender, EventArgs e ) {
if( clickCount > 0 ) {
clickCount = 2;
return;
}
clickCount = 1;
await Task.Delay( SystemInformation.DoubleClickTime );
if( clickCount == 1 ) {
// Process single click ...
} else if( clickCount == 2 ) {
// Process double click ...
}
clickCount = 0;
}

PointerPressed: left or right button?

How can I get the type of pressed pointer (left mouse down or right mouse down) in a Metro style C# app? I didn't find a MouseLeftButtonDown event handler in any Metro style UI element. I should use PointerPressed event instead, but I don't know how can i get which button was pressed.
PointerPressed is enough to handle mouse buttons:
void MainPage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
// Check for input device
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
{
var properties = e.GetCurrentPoint(this).Properties;
if (properties.IsLeftButtonPressed)
{
// Left button pressed
}
else if (properties.IsRightButtonPressed)
{
// Right button pressed
}
}
}
You can use the following event to determine what pointer is used and what button is pressed.
private void Target_PointerMoved(object sender, PointerRoutedEventArgs e)
{
Windows.UI.Xaml.Input.Pointer ptr = e.Pointer;
Windows.UI.Input.PointerPoint ptrPt = e.GetCurrentPoint(Target);
if (ptrPt.Properties.IsLeftButtonPressed)
{
//Do stuff
}
if (ptrPt.Properties.IsRightButtonPressed)
{
//Do stuff
}
}
Working on a UWP project and previous answers like
Properties.IsLeftButtonPressed/IsRightButtonPressed did not work for me. Those values are always false. I realized during the Debugging that Properties.PointerUpdateKind was changing according to mouse button. Here is the result which worked for me:
var properties = e.GetCurrentPoint(this).Properties;
if (properties.PointerUpdateKind == Windows.UI.Input.PointerUpdateKind.LeftButtonReleased)
{
}
else if (properties.PointerUpdateKind == Windows.UI.Input.PointerUpdateKind.RightButtonReleased)
{
}
else if (properties.PointerUpdateKind == Windows.UI.Input.PointerUpdateKind.MiddleButtonReleased)
{
}
There are more options in PointerUpdateKind like ButtonPressed varities of the ones in the example and XButton varities e.g. XButton1Pressed, XButton2Released etc.

Did "MouseUp" event change value of NumericUpDown?

I need to determine if the value of a NumericUpDown control was changed by a mouseUp event.
I need to call an expensive function when the value of a numericupdown has changed. I can't just use "ValueChanged", I need to use MouseUp and KeyUp events.
Basically, I need to know:
Did the value of the numericUpDown change when the user let go of the
mouse? If any area which is not highlighted in red is clicked, the
answer is no. I need to IGNORE the mouse up event, when ANYWHERE but the red area is clicked.
How can I determine this by code? I find events a little confusing.
This will fire when the user releases the mouse button. You might want to investigate which mousebutton was released.
EDIT
decimal numvalue = 0;
private void numericUpDown1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && numvalue != numericUpDown1.Value)
{
//expensive routines
MessageBox.Show(numericUpDown1.Value.ToString());
}
numvalue = numericUpDown1.Value;
}
EDIT 2
This will determine if the left mousebutton is still down, if it is exit before performing expensive routine, doesn't help with keyboard button down.
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left)
{
return;
}
//expensive routines
}
Edit 3
How to detect the currently pressed key?
Will help solve the Any key down, Though I think the only ones that matter are the arrow keys
Problem - I need to IGNORE the mouse up event, when ANYWHERE but the red area is clicked.
Derive a custom numeric control as shown below. Get the TextArea of the Numeric Control and ignore the KeyUp.
class UpDownLabel : NumericUpDown
{
private Label mLabel;
private TextBox mBox;
public UpDownLabel()
{
mBox = this.Controls[1] as TextBox;
mBox.Enabled = false;
mLabel = new Label();
mLabel.Location = mBox.Location;
mLabel.Size = mBox.Size;
this.Controls.Add(mLabel);
mLabel.BringToFront();
mLabel.MouseUp += new MouseEventHandler(mLabel_MouseUp);
}
// ignore the KeyUp event in the textarea
void mLabel_MouseUp(object sender, MouseEventArgs e)
{
return;
}
protected override void UpdateEditText()
{
base.UpdateEditText();
if (mLabel != null) mLabel.Text = mBox.Text;
}
}
In the MainForm, update your designer with this control i.e. UpDownLabel:-
private void numericUpDown1_MouseUp(object sender, MouseEventArgs e)
{
MessageBox.Show("From Up/Down");
}
Referred from - https://stackoverflow.com/a/4059473/763026 & handled the MouseUp event.
Now, use this control instead of the standard one and hook on the
KeyUp event. You will always get the KeyUp event from the Up/Down button only i.e. RED AREA when you click the
spinner [Up/Down button, which is again a different control derived
from UpDownBase].
I think you should use Leave event that when the focus of NumericUpDown control gone, it would called.
int x = 0;
private void numericUpDown1_Leave(object sender, EventArgs e)
{
x++;
label1.Text = x.ToString();
}

Copy item from one listbox to another on double click. Doubleclick event not fired. Winform C#

I am quite new to Winform dev. I have two list boxes. When the user double clicks an item in the first listbox, I want this to be copied to the second list box. The problem is that my double click method never gets fired.
here's my code:
//here I register the event
this.fieldsArea.MouseDoubleClick += new MouseEventHandler(fieldsArea_MouseDoubleClick);
Then here is the double click method:
private void fieldsArea_MouseDoubleClick(object sender, MouseEventArgs e)
{
MessageBox.Show("from method");
int index = fieldsArea.IndexFromPoint(e.Location);
string s = fieldsArea.Items[index].ToString();
selectedFieldsArea.Items.Add(s);
}
So I want the element from fieldsArea to be copied to selectedFieldsArea... The messagebox never shows and in debug I see that I never enter this method...
Am I missing something here?
ps: I have drag drop implemented which works well.
UPDATE: The problem comes from the MouseDown event also being implemented. So here's my mousedown event.
private void fieldsArea_MouseDown(object sender, MouseEventArgs e)
{
if (fieldsArea.Items.Count == 0)
return;
int index = fieldsArea.IndexFromPoint(e.Location);
string s = fieldsArea.Items[index].ToString();
DragDropEffects dde1 = DoDragDrop(s,
DragDropEffects.All);
}
ps: I have drag drop implemented which works well.
That means probably that you have registered a MouseDown event, which interfere with the MouseDoubleclick.
Just for testing purpose, try to delete the Drag&Drop implementation ( unregister the MouseDown event) and then the MouseDoubleclick should work.
Make sure you don't have other Mouse event like MouseClick MouseDown event registered, which could interfere with MouseDoubleclick event.
Update:
Add following code in your MouseDown event handler, you can check if it is a double-click first.
if(e.Clicks>1)
{
int index = fieldsArea.IndexFromPoint(e.Location);
string s = fieldsArea.Items[index].ToString();
selectedFieldsArea.Items.Add(s);
}
so here is your new handler:
private void fieldsArea_MouseDown(object sender, MouseEventArgs e)
{
if (fieldsArea.Items.Count == 0)
return;
int index = fieldsArea.IndexFromPoint(e.Location);
string s = fieldsArea.Items[index].ToString();
if(e.Clicks>1)
{
selectedFieldsArea.Items.Add(s);
}
else
{
DragDropEffects dde1 = DoDragDrop(s,
DragDropEffects.All);
}
}
I believe you may have either "MouseClick/MouseDown" event or "SelectedIndexChanged" event, these events resist to get fire of "MouseDoubleclick" event, so you need to handle them properly. Thanks

Capture mouse movement event only when Left Click is pressed

I need to update a control only whenever the mouse moves over it with the left mouse button pressed. I would normally simply check for the e.Button property, but it is unavailable in the MouseEnter event.
void MyControl_MouseEnter(object sender, EventArgs e)
{
// MouseEventArgs needed to check this
// if (e.Button == MouseButtons.Left)
// {
// update MyControl
// }
}
How would you accomplish this?
Use the static Control.MouseButtons property. For example:
private void panel1_MouseEnter(object sender, EventArgs e) {
if (Control.MouseButtons == MouseButtons.Left) {
// etc...
}
}
This is very difficult to get going, whatever the user clicks on to get the mouse button pressed is going to capture the mouse, preventing the control's MouseEnter event from firing. It is also UI that's completely undiscoverable to the user. Do consider a better mouse trap.
Here's one (crude) way to do it. It will change the form's title text to whatever mouse button was pressed as you dragged your mouse on to button1. You can reference Control.MouseButtons to see which button is in a pressed state. Here's some more info on MSDN.
public partial class Form1 : Form
{
MouseButtons _buttons;
public Form1()
{
InitializeComponent();
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (_buttons != System.Windows.Forms.MouseButtons.None)
{
this.Text = _buttons.ToString();
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
_buttons = Control.MouseButtons;
}
}
I found the answer in another question here on SO:
How can I detect a held down mouse button over a PictureBox?
You will need to use a message filter. Implement the PreFilterMessage of the IMessageFilter interface, and assign an instance using Application.AddMessageFilter.
You will have to interpret windows messages yourself... that is not kind of difficult, but it will require some work.
The implementation may look like this:
if (m.Msg == 0x200)
{
int x, y;
x = m.LParam.ToInt32() & 0xFFFF;
y = m.LParam.ToInt32() >> 16;
if ((m.WParam.ToInt32() & 2) != 0)
{
// here, the left mouse button is pressed, and you can use the coords
// and see if the mouse is over the control you want.
}
}
I just implemented something like this today, tested only in Chrome but works rather nicely. Basic concept is that you capture mousemove only between mousedown and mouseup, as follows:
var image = document.getElementById('my_image');
image.addEventListener('mousedown', function(e) {
e.currentTarget.addEventListener('mousemove', doMyStuff);
});
image.addEventListener('mouseup', function(e) {
e.currentTarget.removeEventListener('mousemove', doMyStuff);
});
function doMyStuff(e) {
// do what you want, the mouse is moving while the user is holding the button down
}
Private Sub Button1_MouseDown(sender As Object, e As MouseEventArgs) Handles
Button1.MouseDown
If Control.MouseButtons = MouseButtons.Left Then
Label1.Text = "Left"
ElseIf Control.MouseButtons = MouseButtons.Right Then
Label1.Text = "Right"
ElseIf Control.MouseButtons = MouseButtons.Middle Then
Label1.Text = "Middle"
Else
Label1.Text = "lelse"
End If
End Sub

Categories