【问题标题】:Disabling double click on winform button禁用双击winform按钮
【发布时间】:2013-11-11 12:04:09
【问题描述】:

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

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

我的限制是我无法更改任一表单上按钮的位置。无论如何我可以处理这个问题吗?

【问题讨论】:

  • 您可以启动一个持续时间较短的计时器,在此期间您不再处理任何点击。
  • 你可以绑定Button.DoubleClick event并禁止它。
  • 附加一个双击事件,然后从该事件中调用默认的单击事件,这使得单击和双击执行相同的操作。

标签: c# winforms


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    试着将新的表单发射到不同的位置。

    据我了解,用户在第一次点击时会触发 frmB 并在“第二次点击”时按 btnB

    不是双击。

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

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

    【讨论】:

    • 他清楚地写了他不能改变按钮的位置。
    • 好的。但我写过关于改变新窗口位置的文章。只是为了从主窗体更高或更低地打开它
    【解决方案3】:

    我会做一些技巧,改变cursor position 怎么样。一旦用户点击 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);
    

    【讨论】:

      【解决方案4】:

      在第一次点击时禁用它,当用户再次打开forma或它来自forma到form b时启用它

      this.button.enable=false;
      

      按下按钮后立即。 并在forma的构造函数中再次写入

      this.button.enable=true;
      

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          您可以使用 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;
              }
          
          }
          

          请注意,我专门为带有 Control.FromHandle() 检查的按​​钮禁用了双击。这将允许双击其他控件,如 ListBoxes 等...

          【讨论】:

            【解决方案7】:

            在您自己的类中,继承基本控件并使用 .SetStyle() 方法禁用双击。以下代码不适用于 Button,但它应该可以正常工作:

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

            【讨论】:

              【解决方案8】:

              启用和禁用按钮的问题在于,如果单击事件中的代码运行得如此之快,以至于在双击操作的第二次单击之前启用了按钮(有些用户不理解它只需要1 点击)所以这是我的解决方案。

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

              【讨论】:

                猜你喜欢
                • 2016-08-03
                • 1970-01-01
                • 2011-07-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-03-19
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多