【问题标题】:Long pressed button长按按钮
【发布时间】:2012-09-29 15:01:38
【问题描述】:

我想在长时间按下Button 时重复一个动作,例如 MP3 阅读器的前进按钮。 WinForm 中是否存在现有的 c# 事件?

我可以处理MouseDown 事件来启动一个计时器,该计时器将执行该操作并在MouseUp 事件上停止它,但我正在寻找一种更简单的方法来解决这个问题=> 即:没有@ 的解决方案987654324@(或线程/任务...)。

【问题讨论】:

    标签: c# winforms button


    【解决方案1】:

    更新:最短路径:

    使用Anonymous MethodsObject 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();
                            };
    }
    

    【讨论】:

    • 最好也取消订阅 MouseUp 上的 Tick 事件。
    • 另外不要忘记丢弃定时器。
    • 您使用的是Timer,而匿名方法只是一种最短的方法,而不是编写真正的方法。这不存在于 Framework 4.0 中吗?
    【解决方案2】:

    您可以在 MouseDown 和 MouseUp 之间使用计时器。

    MouseDownEvent
    
    Timer tm1;
    
    MouseUpEvent
    
    Timer tm2;
    

    您可以在两个计时器之间轻松处理它们。

    【讨论】:

      【解决方案3】:

      您需要在按下按钮时执行一些操作,例如在 MP3 曲目中跳过几秒钟。

      启动一个在 mouseUp 上取消的计时器,在按钮按下时定期(100 毫秒?)触发这种工作对我来说似乎是可行的。易于实现且在 UI 上无阻塞。

      更简单的解决方案可能会导致 UI 阻塞。

      【讨论】:

        【解决方案4】:

        我可以处理 MouseDown 事件来启动一个计时器,该计时器将执行该操作并在 MouseUp 事件上停止它,但我正在寻找一种更简单的方法来解决这个问题

        您可以通过以可重复使用的方式编写一次来简化它。您可以派生具有此行为的自己的 Button 类。

        或者编写一个可以附加到任何按钮的类来赋予它这种行为。例如,您可以执行以下操作:

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

        然后您将按如下方式使用它:

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

        或更简洁地说,因为您不需要保留对ButtonClickRepeater 的引用:

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

        【讨论】:

          【解决方案5】:

          最短的方式(并且没有任何任务/线程/计时器和秒表):)

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

          【讨论】:

          • 秒表类是一个计时器!在框架端处理定时器/任务/线程仍然没有解决方案。
          • 最短路径(并且没有任何任务/线程/计时器和秒表):)
          猜你喜欢
          • 1970-01-01
          • 2021-10-07
          • 2020-10-26
          • 2019-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多