65.9K
CodeProject 正在变化。 阅读更多。
Home

10 分钟内实现自动重复按钮

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.68/5 (24投票s)

2013年8月2日

CPOL

4分钟阅读

viewsIcon

58716

downloadIcon

1236

简单的 WinForms 自动重复按钮,几行代码即可完成

引言

 

你是否曾需要一个按钮,能够模仿键盘的自动重复行为?也就是说,当按钮被点击并按住时,只要按钮被按下,它就会发出一个 MouseDown 事件序列。

我的程序需要这样一个按钮。照例,我开始在CodeProject上搜索,并找到了一个有趣的帖子 Joe 的自动重复按钮类的 .NET 移植版,作者是 Nish Sivakumar。提出的代码完成了它的任务,我正准备将其复制并粘贴到我的项目中,这时我意识到,我可以用更简单的逻辑和更少的代码来实现所需的功能。

背景

基本思路与原文章相同:使用一个定时器控件周期性地执行代码,模拟按住按钮时的多次 MouseDown 事件。

代码

既然我承诺实现起来简单快捷,那么我们就开始吧。

首先,我创建了一个继承自 ButtonRepeatButton 用户控件。

public class RepeatButton : Button  

其次,我添加了一个 Timer 控件,并将其重命名为 timerRepeater。首先,我添加了一个空的 tick 事件处理程序

private void timerRepeater_Tick(object sender, EventArgs e)
{
 //Will be coded later
}

第三,我定义了两个新属性来控制重复时序

[DefaultValue(400)]
public int InitialDelay { set; get; }

[DefaultValue(62)]
public int RepeatInterval { set; get; } 

我确保了属性在构造函数中得到正确初始化

public RepeatButton():base()
{
    InitializeComponent();
    InitialDelay = 400;
    RepeatInterval = 62;
}

接下来,我重写了 OnMouseDown 事件处理程序。新代码做了三件事

  • 它将事件参数保存到一个外部变量。这是必需的,因为事件实际上将由 timerRepeat_Tick 事件处理程序处理,而该处理程序需要这些信息。
  • 它确保 timerRepeater 是禁用的。这行代码实际上不是必需的,因为在执行 OnMouseDowntimerRepeater 总是被禁用的。我在这里添加它是为了代码的清晰性。
  • 它调用 timerRepeater_Tick,该调用将立即处理初始单击以及在鼠标按住期间的所有重复。
MouseEventArgs MouseDownArgs = null;
protected override void OnMouseDown(MouseEventArgs mevent)
{
    MouseDownArgs = mevent;
    timerRepeater.Enabled = false;
    timerRepeater_Tick(null, EventArgs.Empty);
}

最后,代码的关键部分,也就是重复循环发生的地方。是时候为 timerRepeater_Tick 填充可用代码了。

当用户按下按钮时,从 OnMouseDown 中显式调用此处理程序。第一行包含对 base.OnMouseDown 的调用。这是实际处理 MouseDown 事件的地方,也是将控件宿主的代码通知鼠标已被按下的地方。

下一篇

如果 timerRepeater 未启用(当 timerRepeater_TickOnMouseDown 调用时,它从未启用),这意味着这是在按下鼠标后第一次调用此代码。在这种情况下,timerRepeater.Interval 被设置为 InitialDelay,否则它被设置为 RepeatInterval

最后一行代码,将 timerRepeater.Enabled 属性设置为 true。这将导致 timerRepeater_TickInterval 属性中设置的时间间隔持续调用。

private void timerRepeater_Tick(object sender, EventArgs e)
{
    base.OnMouseDown(MouseDownArgs);
    if (timerRepeater.Enabled)
        timerRepeater.Interval = RepeatInterval;
    else
        timerRepeater.Interval = InitialDelay;
 
     timerRepeater.Enabled = true;
}

上述代码将在鼠标初始按下后永远被调用。我们需要在鼠标再次抬起时停止此行为。没有比这更简单的了。在 OnMouseUp 中需要额外的一行代码,将 timerRepeater.Enabled 属性设置为 false。这将立即停止 timerRepeater_Tick 循环。

protected override void OnMouseUp(MouseEventArgs mevent)
{
    base.OnMouseUp(mevent);
    timerRepeater.Enabled = false;
}

好了,这就是完整的、功能性的 RepeatButton,可能用时甚至不到 10 分钟。

RepeatButton 的全部代码如下所示,您可以将其复制并粘贴到您的解决方案中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Windows.Forms;
using System.ComponentModel;
 
namespace RepeatButtonControl
{
    public class RepeatButton : Button
    {
        private Timer timerRepeater;
        private IContainer components;
    
        public RepeatButton():base()
        {
            InitializeComponent();
 
            InitialDelay = 400;
            RepeatInterval = 62;
        }
 
        [DefaultValue(400)]
        public int InitialDelay { set; get; }
 
        [DefaultValue(62)]
        public int RepeatInterval { set; get; }
 
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timerRepeater = new System.Windows.Forms.Timer(this.components);
            this.SuspendLayout();
            this.timerRepeater.Tick += new System.EventHandler(this.timerRepeater_Tick);
            this.ResumeLayout(false);
         }
        
        MouseEventArgs MouseDownArgs = null;
        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            //Save arguments
            MouseDownArgs = mevent;
            timerRepeater.Enabled = false;
            timerRepeater_Tick(null, EventArgs.Empty);
        }
 
        private void timerRepeater_Tick(object sender, EventArgs e)
        {
 
            base.OnMouseDown(MouseDownArgs);
            if (timerRepeater.Enabled)
                timerRepeater.Interval = RepeatInterval;
            else
                timerRepeater.Interval = InitialDelay;
 
            timerRepeater.Enabled = true;
        }
 
        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            base.OnMouseUp(mevent);
            timerRepeater.Enabled = false;
        }
    }
} 

Using the Code

您可以跟着代码,重复文章中描述的所有步骤,从头开始开发一个重复按钮,这很容易也很有趣。

如果您想节省时间,也可以下载附带的源代码。它包含 RepeatButton 的源代码和一个演示应用程序,说明了重复按钮的行为。无需过多解释。

您在演示主屏幕上按下 repeatButton,按住它,然后观察事件的生成情况,如下面的屏幕截图所示

可下载的 zip 文件还包含帮助文件 (chm)。请注意,由于您是从互联网下载此文件,为了使用它,您必须先取消阻止。您可以在 Windows 资源管理器中执行此操作:右键单击帮助文件,选择“**属性**”,然后单击“**取消阻止**”按钮。

历史

  • 2013年8月1日 - 初始发布
  • 2013年9月17日 - 更新了源代码:改进了样式,添加了注释,添加了 Dispose 方法,为控件添加了帮助文件 (chm)
  • 2013年12月13日 - 对文章文本进行了小幅改进
© . All rights reserved.