在C#中,如何防止PreviewKeyDown事件在某些代码完成之前被多次按下?

在C#中,如何防止PreviewKeyDown事件在某些代码完成之前被多次按下?,c#,winforms,C#,Winforms,我设置了一个摄像头应用程序,我的问题是人们可能会多次按下按钮,导致脚本混乱: private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e) { if (e.KeyCode == Keys.Space) { var timer = new System.Timers.Timer(1000); int count = 0; timer.SynchronizingObj

我设置了一个摄像头应用程序,我的问题是人们可能会多次按下按钮,导致脚本混乱:

private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e) {
  if (e.KeyCode == Keys.Space) {
    var timer = new System.Timers.Timer(1000);
    int count = 0;
    timer.SynchronizingObject = this;
    timer.AutoReset = true;
    timer.Elapsed += delegate {
      count++;
      if (count == 1) {
        label1.Text = File.ReadAllText("Countdown_3.txt");
      }
      if (count == 3) {
        label1.Text = File.ReadAllText("Countdown_2.txt");
      }
      if (count == 5) {
        label1.Text = File.ReadAllText("Countdown_1.txt");
      }
      if (count == 7) {
        webcam.Stop();
        label1.Text = File.ReadAllText("ImageCapturedPlusFrozen.txt");
      }
      if (count == 9) {
        label1.Text = File.ReadAllText("IdleForPreview.txt");
        label1.Refresh();
        Directory.CreateDirectory(DateTime.Now.ToString("yyyy-MM-dd"));
        using (Bitmap bmp = new Bitmap(imgVideo.ClientSize.Width, imgVideo.ClientSize.Height)) {
          using (Graphics g = Graphics.FromImage(bmp)) {
            g.DrawImage(imgVideo.Image,
              new Rectangle(0, 0, bmp.Width, bmp.Height),
              new Rectangle(0, 0, imgVideo.Image.Width, imgVideo.Image.Height),
              GraphicsUnit.Pixel);
          }
          bmp.Save(DateTime.Now.ToString("yyyy-MM-dd") + "/ " + DateTime.Now.ToString("HH-mm-ss") + ".png", ImageFormat.Png);
        }
      }
      if (count == 20) {
        label1.Text = "Press Button to Start!";
        webcam.Start();
        timer.Stop();
      }
    };
    timer.Start();
  }
}

我如何才能禁用按键,直到计时器完成?我试过像KeyPreview=false这样的东西;但那不行

您可以添加一个
bool
标志,指示是否有工作正在完成。然后在按键时检查该标志

bool flag = false;

private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (!flag)
        {

                flag = true;
                \\.....
                if (count == 20)
                {
                    \\.......
                    timer.Stop();
                    flag = false;
                }

            timer.Start();
        }
    }

也许使用bool作为主控制回路的一部分?(将其初始化为
true


快速解决方案是设置按钮文本框控件的
已启用
属性

如果该控件被调用为
objCtrl

private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e) {
  if (e.KeyCode == Keys.Space) {
    objCtrl.Enabled = false;
    var timer = new System.Timers.Timer(1000);
    int count = 0;
    timer.SynchronizingObject = this;
    timer.AutoReset = true;
    timer.Elapsed += delegate {
      count++;
      if (count == 1) {
        label1.Text = File.ReadAllText("Countdown_3.txt");
      }
      if (count == 3) {
        label1.Text = File.ReadAllText("Countdown_2.txt");
      }
      if (count == 5) {
        label1.Text = File.ReadAllText("Countdown_1.txt");
      }
      if (count == 7) {
        webcam.Stop();
        label1.Text = File.ReadAllText("ImageCapturedPlusFrozen.txt");
      }
      if (count == 9) {
        label1.Text = File.ReadAllText("IdleForPreview.txt");
        label1.Refresh();
        Directory.CreateDirectory(DateTime.Now.ToString("yyyy-MM-dd"));
        using (Bitmap bmp = new Bitmap(imgVideo.ClientSize.Width, imgVideo.ClientSize.Height)) {
          using (Graphics g = Graphics.FromImage(bmp)) {
            g.DrawImage(imgVideo.Image,
              new Rectangle(0, 0, bmp.Width, bmp.Height),
              new Rectangle(0, 0, imgVideo.Image.Width, imgVideo.Image.Height),
              GraphicsUnit.Pixel);
          }
          bmp.Save(DateTime.Now.ToString("yyyy-MM-dd") + "/ " + DateTime.Now.ToString("HH-mm-ss") + ".png", ImageFormat.Png);
        }
      }
      if (count == 20) {
        label1.Text = "Press Button to Start!";
        webcam.Start();
        timer.Stop();
        objCtrl.Enabled = true;
      }
    };
    timer.Start();
  }
}

将计时器从方法内部移动到外部,以便通过多次调用事件处理程序来利用if

比如:

private var timer = new System.Timers.Timer(1000);

private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space && !timer.Enabled)
        {
                int count = 0;
                timer.SynchronizingObject = this;
                timer.AutoReset = true; 
                timer.Elapsed += delegate

            {
                count++;
                if (count == 1)
                {
                    label1.Text = File.ReadAllText("Countdown_3.txt");
                }
                if (count == 3)
                {
                    label1.Text = File.ReadAllText("Countdown_2.txt");
                }
                if (count == 5)
                {
                    label1.Text = File.ReadAllText("Countdown_1.txt");
                }
                if (count == 7)
                {
                    webcam.Stop();
                    label1.Text = File.ReadAllText("ImageCapturedPlusFrozen.txt");
                }
                if (count == 9)
                {
                    label1.Text = File.ReadAllText("IdleForPreview.txt");
                    label1.Refresh();
                    Directory.CreateDirectory(DateTime.Now.ToString("yyyy-MM-dd"));
                    using (Bitmap bmp = new Bitmap(imgVideo.ClientSize.Width,
                            imgVideo.ClientSize.Height))
                    {
                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            g.DrawImage(imgVideo.Image,
                                        new Rectangle(0, 0, bmp.Width, bmp.Height),
                                        new Rectangle(0, 0, imgVideo.Image.Width, imgVideo.Image.Height),
                                        GraphicsUnit.Pixel);
                        }
                        bmp.Save(DateTime.Now.ToString("yyyy-MM-dd") + "/ " + DateTime.Now.ToString("HH-mm-ss") + ".png", ImageFormat.Png);
                    }
                }
                if (count == 20)
                {
                    label1.Text = "Press Button to Start!";
                    webcam.Start();
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }

取消订阅活动,然后在计时器完成后重新订阅。简单、优雅以及更多logical@Ahmedilyas取消订阅和重新订阅事件处理程序可能会变得繁琐且容易出错。最好用一个门来锁定事件处理程序代码,以检查进程是否已经发生。@Etherdagon-当然,但订阅和取消订阅并不那么困难。例如,一些系统在不同的情况下对按钮事件处理程序执行相同的操作。我仍然认为,在不同的情况下/场景下,使用本地计时器变量会给自己带来很大的麻烦,在将来执行锁操作实际上会有更多的麻烦。当用户关闭窗口且计时器仍在滴答作响时,您预计会发生什么?让它成为你班上的一员。现在更容易停止。如果(timer.Enabled)返回,您可以简单地添加
if忽略按键。比我快一分钟!:)快速打字-我建议他们将计时器移到更高的范围,并利用它。
private var timer = new System.Timers.Timer(1000);

private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space && !timer.Enabled)
        {
                int count = 0;
                timer.SynchronizingObject = this;
                timer.AutoReset = true; 
                timer.Elapsed += delegate

            {
                count++;
                if (count == 1)
                {
                    label1.Text = File.ReadAllText("Countdown_3.txt");
                }
                if (count == 3)
                {
                    label1.Text = File.ReadAllText("Countdown_2.txt");
                }
                if (count == 5)
                {
                    label1.Text = File.ReadAllText("Countdown_1.txt");
                }
                if (count == 7)
                {
                    webcam.Stop();
                    label1.Text = File.ReadAllText("ImageCapturedPlusFrozen.txt");
                }
                if (count == 9)
                {
                    label1.Text = File.ReadAllText("IdleForPreview.txt");
                    label1.Refresh();
                    Directory.CreateDirectory(DateTime.Now.ToString("yyyy-MM-dd"));
                    using (Bitmap bmp = new Bitmap(imgVideo.ClientSize.Width,
                            imgVideo.ClientSize.Height))
                    {
                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            g.DrawImage(imgVideo.Image,
                                        new Rectangle(0, 0, bmp.Width, bmp.Height),
                                        new Rectangle(0, 0, imgVideo.Image.Width, imgVideo.Image.Height),
                                        GraphicsUnit.Pixel);
                        }
                        bmp.Save(DateTime.Now.ToString("yyyy-MM-dd") + "/ " + DateTime.Now.ToString("HH-mm-ss") + ".png", ImageFormat.Png);
                    }
                }
                if (count == 20)
                {
                    label1.Text = "Press Button to Start!";
                    webcam.Start();
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }