3

I have tried all day, and looked up all kinds of ideas... with no real help. When I press a button, like "JOG", which would move a CNC Machine axis continuously, as long a the button is pressed, then when released, it would stop.

To test this I am using a "picuture / LED" which when I press and hold, should be on... and when I release, it should turn off.

Pressed Button should = only while pressed, do something. Release of same button = stop doing whatever you were doing now.

I am sure for you advanced folks, this is maybe 101... but for me... it is eating my lunch... help?

jeffserv
  • 69
  • 2
  • 9

5 Answers5

6

You can use the MouseDown and MouseUp events. When the MouseDown event is hit, call a method that loops and performs your action. Once MouseUp is hit, stop the loop.

private bool _run = false;

public void button_MouseDown(object sender, EventArgs e)
{
    _run = true;
    MyAction();
}

public void button_MouseUp(object sender, EventArgs e)
{
    _run = false;
}

public void MyAction()
{
    while(_run)
    {
        //You actions
    }
}

Note that the above example will hog up the UI thread. You should run it on another thread using a BackgroundWorker or something similar.

Dave Zych
  • 21,581
  • 7
  • 51
  • 66
  • 3
    Without threading this may lock up your UI. Be careful on this. Otherwise good solution. – Matt Jan 15 '14 at 20:08
  • Thanks,... I will try this mouse code on the buttons that need this feature. I will report back what I am able to do. – jeffserv Jan 15 '14 at 20:17
3

Generically, have a look at the mouse up and down events. I would have it call some function asynchronously (not on the UI thread) when the mouse is down. And stop it when the mouse up event fires. System.Threading has some nice models for this. Try googling around there.

You are wanting to start and stop a thread where the procedure is looping performing your action.

Matt
  • 1,441
  • 1
  • 15
  • 29
1

I'd make my own subclass, something like this:

public class RepeatButton : Button
{
    readonly Timer timer = new Timer();

    public event EventHandler Depressed;

    public virtual TimeSpan Interval
    {
        get { return TimeSpan.FromMilliseconds(timer.Interval); }
        set { timer.Interval = (int)value.TotalMilliseconds; }
    }

    public RepeatButton()
    {
        timer.Interval = 100;
        timer.Tick += delegate { OnDepressed(); };
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);
        timer.Stop();
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        timer.Start();
    }

    protected virtual void OnDepressed()
    {
        var handler = this.Depressed;

        if (handler != null)
            handler(this, EventArgs.Empty);
    }
}

This allows your code to be asynchronous but also the Depressed event would be invoked on the UI thread still.

Erik
  • 12,730
  • 5
  • 36
  • 42
1

Consider Space bar to trigger button down and up as well.

this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.button1_MouseDown);
this.button1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.button1_MouseUp); 

this.button1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.button1_KeyDown);
this.button1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.button1_KeyUp);

private void button1_MouseDown(object sender, MouseEventArgs e) 
{
  led18.Show();
} 

private void button1_MouseUp(object sender, MouseEventArgs e) 
{
  led18.Hide();  
}

private void button1_KeyDown(object sender, KeyEventArgs e)
{
    if(e.KeyCode == Keys.Space && e.Alt==false && e.Control==false && e.Shift==false)
    {
        led18.Show();
    }
}
private void button1_KeyUp(object sender, KeyEventArgs e)
{
    led18.Hide();  
}
Yang Jk
  • 577
  • 6
  • 9
  • +1 for thinking about keyboard, too, isn't there any universal event which fires when button is "activated", no matter if by mouse or by keyboard (with default key bindings in Windows Forms)? – user3625699 Jan 25 '22 at 11:18
0

Thanks all, this is about as simple as I could get it. Button and Mouse control mixed togather, needs mouse handling... which is added in the button properties, which will add the code to the designer.

private void button2_MouseDown(object sender, MouseEventArgs e) 
{
  led18.Show();
} 

private void button2_MouseUp(object sender, MouseEventArgs e) 
{
  led18.Hide();  
}

//below get automatically put into the design file...

this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.button1_MouseDown);
this.button1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.button1_MouseUp); 
jeffserv
  • 69
  • 2
  • 9