C# 禁用双击winform按钮

C# 禁用双击winform按钮,c#,winforms,C#,Winforms,我在C#Net中开发了一个windows窗体应用程序。应用程序中有多个表单。主窗体表示frmA有一个按钮表示btnA。点击btnA,新的表单显示frmB打开,frmA在frmB后面。frmB还有一个按钮,表示btnB,frmB上btnB的位置(位置)与frmA上btnA的位置(位置)完全相同。单击btnB时,会发生一些不同的操作 现在我的问题是一些应用程序用户双击btnA。我得到两个单一的点击背靠背。在第一次单击btnA时,frmB将使用btnB打开。第二次单击会立即在btnB上执行,实际上用户

我在C#Net中开发了一个windows窗体应用程序。应用程序中有多个表单。主窗体表示frmA有一个按钮表示btnA。点击btnA,新的表单显示frmB打开,frmA在frmB后面。frmB还有一个按钮,表示btnB,frmB上btnB的位置(位置)与frmA上btnA的位置(位置)完全相同。单击btnB时,会发生一些不同的操作

现在我的问题是一些应用程序用户双击btnA。我得到两个单一的点击背靠背。在第一次单击btnA时,frmB将使用btnB打开。第二次单击会立即在btnB上执行,实际上用户甚至看不到frmB


我的限制是,我无法更改两个窗体上按钮的位置。有什么方法可以解决这个问题吗?

试着把新表单放到不同的位置

据我所知,用户在第一次单击时就会触发frmB 并在“第二次单击”时按btnB

这不是双击

这是两次不同的点击 试试这样:

Form2 form=new Form2();  
form.StartPosition = FormStartPosition.Manual;  
form.Location=new Point(0, 10);  
form.Show(); 

当用户再次打开forma或它从forma到form b时,在第一次单击时禁用它

this.button.enable=false;
按下按钮后立即停止。 然后在forma的构造函数中再次写入

this.button.enable=true;

将btnB.Enabled设置为false并使用以下代码。这将使单击按钮的时间延迟半秒

public partial class frmB : Form
{
    private Timer buttonTimer = new Timer();

    public frmB()
    {
        InitializeComponent();
        buttonTimer.Tick += new EventHandler(buttonTimer_Tick);
        buttonTimer.Interval = 500;
    }

    private void frmB_Shown(object sender, EventArgs e)
    {
        buttonTimer.Start();
    }

    void buttonTimer_Tick(object sender, EventArgs e)
    {
        btnB.Enabled = true;
        buttonTimer.Stop();
    }
}

我同意此UI不友好,但如果您绝对无法更改按钮的位置或第二个表单的打开位置,则需要停止导致frmB关闭的第二次单击。最简单的方法是在打开表格时延迟,例如

public partial class FormB : Form
    {
        public FormB()
        {
            InitializeComponent();
            Thread.Sleep(2000);
        }
    }

我会做一些技巧,改变
光标位置如何。一旦用户单击btnA,光标点将移动一点,以便第二次单击不会击中btnB

this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X - 50, Cursor.Position.Y - 50);
Cursor.Clip = new Rectangle(this.Location, this.Size);

您可以使用IMessageFilter检测WM_LBUTTONDOWN消息,并在特定时间阈值内抑制它们:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
        Application.AddMessageFilter(new DoubleClickSuppressser());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 f2 = new Form2();
        f2.StartPosition = FormStartPosition.Manual;
        f2.Location = this.Location;
        f2.Show();
    }

    private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        Console.WriteLine("listBox1 DoubleClick");
    }

}

public class DoubleClickSuppressser : IMessageFilter
{

    private int difference;
    private DateTime Last_LBUTTONDOWN = DateTime.MinValue;
    private const int WM_LBUTTONDOWN = 0x201;

    public bool PreFilterMessage(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_LBUTTONDOWN:
                if (Control.FromHandle(m.HWnd) is Button)
                {
                    if (!Last_LBUTTONDOWN.Equals(DateTime.MinValue))
                    {
                        difference = (int)DateTime.Now.Subtract(Last_LBUTTONDOWN).TotalMilliseconds;
                        Last_LBUTTONDOWN = DateTime.Now;
                        if (difference < System.Windows.Forms.SystemInformation.DoubleClickTime)
                        {
                            return true;
                        }
                    }
                    Last_LBUTTONDOWN = DateTime.Now;
                }
                break;
        }
        return false;
    }

}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
AddMessageFilter(新的双击抑制器());
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
Form2 f2=新的Form2();
f2.StartPosition=FormStartPosition.Manual;
f2.位置=此位置;
f2.Show();
}
私有无效列表框1u MouseDoubleClick(对象发送方,MouseEventArgs e)
{
Console.WriteLine(“listBox1双击”);
}
}
公共类双击抑制器:IMessageFilter
{
私人智力差异;
private DateTime Last_LBUTTONDOWN=DateTime.MinValue;
私有常量int WM_LBUTTONDOWN=0x201;
公共bool预过滤器消息(参考消息m)
{
开关(m.Msg)
{
案例WM_LBUTTONDOWN:
if(控件FromHandle(m.HWnd)为按钮)
{
如果(!Last_LBUTTONDOWN.Equals(DateTime.MinValue))
{
差=(int)DateTime.Now.Subtract(Last_LBUTTONDOWN.total毫秒;
Last_LBUTTONDOWN=DateTime.Now;
if(差异

请注意,我专门禁用了仅对带有控件.FromHandle()检查的按钮双击。这将允许双击在其他控件(如列表框等)上工作。

在您自己的类中,继承基本控件并使用.SetStyle()方法禁用双击。以下代码不适用于按钮,但其工作原理应相同:

public class MOBIcon : PictureBox
{
    public MOBIcon() : base()
    {
        this.SetStyle(ControlStyles.StandardDoubleClick, false);
    }
}

启用和禁用按钮的问题是,如果单击事件中的代码运行得太快,以至于在双击操作的第二次单击之前按钮被启用(一些用户不理解只需单击一次),那么下面是我的解决方案

private const int waittime = 2;
private DateTime clickTime = DateTime.Now;

private void cmd_TimeStamp_Click(object sender, EventArgs e)
{
  if ((DateTime.Now - clickTime).Seconds < waittime)
    return;
  else
    clickTime = DateTime.Now;
  try
  {
    cmd_TimeStamp.Enabled = false;
    //Do some stuff in here
  }
  catch (Exception ex)
  {
    //Show error if any
    MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  }
  finally
  {
    cmd_TimeStamp.Enabled = true;
  }
}
private const int waittime=2;
private DateTime clickTime=DateTime.Now;
private void cmd_TimeStamp_Click(对象发送方,事件参数e)
{
如果((DateTime.Now-clickTime).Seconds
你可以启动一个时间很短的计时器,在此期间你不会再处理任何点击。你可以绑定并抑制它。附加一个双击事件,然后从该事件调用默认的单击事件,使单击和双击做相同的事情。他清楚地写道,他不能更改按钮的位置。好的。但我写过关于改变新窗口位置的文章。只需从主窗体向上或向下打开它