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