Did "MouseUp" event change value of NumericUpDown? - c#

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();
}

Related

Put focus back on previously focused control on a button click event C# winforms

I have made a custom Number Keypad control that I want to place in my winform application. All of the buttons have an OnClick event to send a value to the focused textbox in my form where I have placed my custom control. Like this:
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null && focusedCtrl is TextBox)
{
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
focusedCtrl is supposed to be set on the MouseDown event of the button like this:
private void btnNum1_MouseDown(object sender, EventArgs e)
{
focusedCtrl = this.ActiveControl;
}
where this.ActiveControl represents the active control on the form.
My problem is that the button always receives the focus before the event detects what the focused control was previously. How can I detect which control had the focus before the button got the focus? Is there another event I should be using? Thanks in advance!
EDIT: Also, I would rather not use the GotFocus event on each textbox in the form to set focusedCtrl since that can be tedious and because I would like to have all the coding of my custom control be in the control itself and not on the form where it is placed. (I will do this, though, if there is no other practical way to do what I am asking)
Your requirement is fairly unwise, you'll want some kind of guarantee that your button isn't going to poke text into inappropriate places. You really do need to have the form co-operate, only it knows what places are appropriate.
But it is not impossible, you can sniff at input events before they are dispatched to the control with the focus. In other words, record which control has the focus before the focusing event is fired. That's possible in Winforms with the IMessageFilter interface.
Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing your existing buttons.
using System;
using System.Windows.Forms;
class CalculatorButton : Button, IMessageFilter {
public string Digit { get; set; }
protected override void OnClick(EventArgs e) {
var box = lastFocused as TextBoxBase;
if (box != null) {
box.AppendText(this.Digit);
box.SelectionStart = box.Text.Length;
box.Focus();
}
base.OnClick(e);
}
protected override void OnHandleCreated(EventArgs e) {
if (!this.DesignMode) Application.AddMessageFilter(this);
base.OnHandleCreated(e);
}
protected override void OnHandleDestroyed(EventArgs e) {
Application.RemoveMessageFilter(this);
base.OnHandleDestroyed(e);
}
bool IMessageFilter.PreFilterMessage(ref Message m) {
var focused = this.FindForm().ActiveControl;
if (focused != null && focused.GetType() != this.GetType()) lastFocused = focused;
return false;
}
private Control lastFocused;
}
Control focusedCtrl;
//Enter event handler for all your TextBoxes
private void TextBoxesEnter(object sender, EventArgs e){
focusedCtrl = sender as TextBox;
}
//Click event handler for your btnNum1
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null){
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
you have an event called lostFocus you can use
button1.LostFocus +=new EventHandler(dataGridView1_LostFocus);
and in the event:
Control lastFocused;
void dataGridView1_LostFocus(object sender, EventArgs e)
{
lastFocused = sender as Control;
}
in that way you can always know what is the Control that was focused previously
now, correct me if i'm wrong, but you do it for the SendKeys.Send("1"); to know which textBox need to receive the number. for that you can use GotFocus event and register only the textBoxs to it.
you can also do what windows is doing and use just one textbox like here:
if it's fits your needs
What about using this with the parameter forward = false?
Control.SelectNextControl Method
You'd probably call it on your "custom Number Keypad control".

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

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.

Creating A Continuous Action During A Windows Form Mouse Event

When I put a button on a form in C#, Visual Studio 2005, and have an action triggered by a button event, such as MouseHover or MouseDown, then the event triggers a single call to the function which defines the action despite the fact that I may continue to hover or keep the left button down. In this case I am trying to move a graphical object by rotating or translating it. I don't want to continue to click the mouse in order to get a repeated call to the transforming function, just keep the mouse hovering or hold the button down. What maintains the action until I cease my own action?
Set a flag on MouseEnter and keep doing the action while the flag remains true. Set the flag to false on MouseLeave.
In your case you need to use a combination of the events MouseDown, MouseMove and MouseUp.
Here a small simplified example to start:
private void OnMouseDown(object sender, EventArgs e)
{
//hit test to check if the mouse pointer is on a graphical object
_myHitObject = the_selected_object
}
private void OnMouseMove(object sender, EventArgs e)
{
if(_myHitObject != null)
//do your action relative to the mouse movements.
}
private void OnMouseUp(object sender, EventArgs e)
{
_myHitObject = null;
}
The solution is to use DoEvents() which allows for the MouseLeave event to be noted and the class variable "more" to be changed:
private void MouseEnter_ZoomIn(object sender, EventArgs e)
{
more = true;
while (more == true)
{
c1Chart3D1.ChartArea.View.ViewportScale *= ZoomMultiple;
Application.DoEvents();
}
} // MOUSEENTER_ZOOMIN()
//-------------------------------------
private void MouseLeave_Stop(object sender, EventArgs e)
{
more = false;
}

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