1

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

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

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

4

8 回答 8

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();
    }
}
于 2013-11-11T12:31:24.853 回答
1

只是尝试将新形式发射到不同的位置。

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

不是双击。

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

Form2 form=new Form2();  
form.StartPosition = FormStartPosition.Manual;  
form.Location=new Point(0, 10);  
form.Show(); 
于 2013-11-11T12:12:49.943 回答
0

在第一次单击时禁用它 当用户再次打开表单或它来自表单到表单 b 时启用它

this.button.enable=false;

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

this.button.enable=true;
于 2013-11-11T12:18:46.693 回答
0

我会做一些技巧,改变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);
于 2013-11-11T13:41:54.993 回答
0

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

public partial class FormB : Form
    {
        public FormB()
        {
            InitializeComponent();
            Thread.Sleep(2000);
        }
    }
于 2013-11-11T12:33:43.293 回答
0

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

public class MOBIcon : PictureBox
{
    public MOBIcon() : base()
    {
        this.SetStyle(ControlStyles.StandardDoubleClick, false);
    }
}
于 2014-04-14T12:09:08.453 回答
0

您可以使用 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 等...

于 2013-11-11T14:08:18.480 回答
0

启用和禁用按钮的问题在于,如果单击事件中的代码运行得如此之快,以至于在双击操作的第二次单击之前启用了按钮(有些用户不明白它只需要单击 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;
  }
}
于 2017-04-27T15:26:39.330 回答