Long pressed button

后端 未结 5 2206
轮回少年
轮回少年 2021-01-18 13:15

I want to repeat an action when a Button is pressed during a long time, like for example the forward button of an MP3 reader. Is there an existing c# event in W

相关标签:
5条回答
  • 2021-01-18 13:36

    shortest way (and without any task/thread/timer & stopwatch) :)

    DateTime sw;
    bool buttonUp = false;
    const int holdButtonDuration = 2000;
    private void btnTest_MouseDown(object sender, MouseEventArgs e)
    {
        buttonUp = false;
        sw = DateTime.Now;
        while (e.Button == MouseButtons.Left && e.Clicks == 1 && (buttonUp == false && (DateTime.Now - sw).TotalMilliseconds < holdButtonDuration))
            Application.DoEvents();
        if ((DateTime.Now - sw).TotalMilliseconds < holdButtonDuration)
            Test_ShortClick();
        else
            Test_LongClick();
    }
    private void btnTest_MouseUp(object sender, MouseEventArgs e)
    {
        buttonUp = true;
    }
    
    0 讨论(0)
  • 2021-01-18 13:42

    I can handle the MouseDown event to start a timer which will perform the action and stop it on MouseUp event, but I am looking for an easier way to solve this problem.

    You can make it easier by writing it once in a reusable way. You could derive your own Button class that has this behaviour.

    Or write a class that you can attach to any button to give it this behaviour. For example you could do something like:

    class ButtonClickRepeater
    {
        public event EventHandler Click;
    
        private Button button;
        private Timer timer;
    
        public ButtonClickRepeater(Button button, int interval)
        {
            if (button == null) throw new ArgumentNullException();
    
            this.button = button;
            button.MouseDown += new MouseEventHandler(button_MouseDown);
            button.MouseUp += new MouseEventHandler(button_MouseUp);
            button.Disposed += new EventHandler(button_Disposed);
    
            timer = new Timer();
            timer.Interval = interval;
            timer.Tick += new EventHandler(timer_Tick);
        }
    
        void button_MouseDown(object sender, MouseEventArgs e)
        {
            OnClick(EventArgs.Empty);
            timer.Start();
        }
    
        void button_MouseUp(object sender, MouseEventArgs e)
        {
            timer.Stop();
        }
    
        void button_Disposed(object sender, EventArgs e)
        {
            timer.Stop();
            timer.Dispose();
        }
    
        void timer_Tick(object sender, EventArgs e)
        {
            OnClick(EventArgs.Empty);
        }
    
        protected void OnClick(EventArgs e)
        {
            if (Click != null) Click(button, e);
        }
    }
    

    You would then use it as follows:

    private void Form1_Load(object sender, EventArgs e)
    {
        ButtonClickRepeater repeater = new ButtonClickRepeater(this.myButton, 1000);
        repeater.Click += new EventHandler(repeater_Click);
    }
    

    or more concisely, since you don't need to keep a reference to ButtonClickRepeater:

    private void Form1_Load(object sender, EventArgs e)
    {
        new ButtonClickRepeater(this.myBbutton, 1000).Click += new EventHandler(repeater_Click);
    }
    
    0 讨论(0)
  • 2021-01-18 13:43

    You will need to perform some action while the button is pressed, like skipping some seconds in the MP3-track.

    Starting a timer that gets cancelled on mouseUp that triggers that kind of work on a regular interval (100ms?) while the button is down seems viable to me. Easy to implement and is non blocking on the UI.

    A more simple solution will probably cause the UI to block.

    0 讨论(0)
  • 2021-01-18 13:48

    You can use timer between MouseDown and MouseUp.

    MouseDownEvent
    
    Timer tm1;
    
    MouseUpEvent
    
    Timer tm2;
    

    You can easily handle them between two timers.

    0 讨论(0)
  • 2021-01-18 14:00

    UPDATED: Shortest way:

    Using Anonymous Methods and Object Initializer:

    public void Repeater(Button btn, int interval)
    {
        var timer = new Timer {Interval = interval};
        timer.Tick += (sender, e) => DoProgress();
        btn.MouseDown += (sender, e) => timer.Start();
        btn.MouseUp += (sender, e) => timer.Stop();
        btn.Disposed += (sender, e) =>
                            {
                                timer.Stop();
                                timer.Dispose();
                            };
    }
    
    0 讨论(0)
提交回复
热议问题