【问题标题】:How to use Key Event in Timer?如何在定时器中使用按键事件?
【发布时间】:2023-03-09 16:40:01
【问题描述】:

我有以下代码,它在按键时开始将两个标签从表单顶部移动到底部,并在到达表单底部后停止。我已经使用计时器完成了它。这是代码

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    label1.Text = "Key Pressed: " + e.KeyChar;
   //animate(sender, e);
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    Random random = new Random();
    int X = random.Next(0, 1230);
    int y = X;
    label2.Location = new Point(X, 5);
    label3.Location = new Point(X + 20, 5 + 20);
    for (int i = 5; i <= 470; i++)
    {
        label2.Location = new Point(y, i);
        label3.Location = new Point(y + 20, i + 20);
        Thread.Sleep(1);
    }
    timer1.Stop();
}

现在在动画期间(从表单顶部到底部),当我按下键时,动画在到达底部后重新开始,即它完成了刻度事件,然后才重新开始或停止。

现在我想要的是,在标签从上到下移动的过程中,即在滴答声期间,如果我按下任何键(或任何特定键),计时器应该停止。

简而言之,在 Timer1_Tick 方法期间,我希望它在按键时立即停止。

我尝试过,但无法正常工作。我希望你们这里的人能帮助我解决这个问题,并希望你们尽早回复。感谢您的宝贵时间!

【问题讨论】:

    标签: c# timer


    【解决方案1】:

    这里的问题是您并没有真正按照预期的方式使用Timer。理想情况下,您将有一个事件在每次为Timer 触发滴答事件时进行更改。

    在这里,您侦听事件并执行几轮处理,而无需从处理程序返回,此时您停止计时器。这意味着代码只会处理一次滴答事件而不是 N 次。

    要解决此问题,请尝试拆分处理程序以在每个刻度上执行一次增量工作,并且仅在绘图完成后停止。这也将允许您在滴答事件之间处理关键事件并停止计时器。分解工作的最佳位置是Thread.Sleep 调用(它本身不应出现在处理程序中)

    【讨论】:

    • 谢谢 JaredPar。问题是现在标签以非常快的速度下降,几乎不可能看到它们所代表的文本。我每次迭代都使用 Thread.Sleep(1) 来控制睡眠。有没有其他方法可以减慢这个速度?
    • @user3206911 尝试增加Timer 的持续时间。使滴答声之间的时间至少一秒钟。如果您只移动票证上的标签,那么移动之间的时间也将至少为一秒
    【解决方案2】:

    试试就这么简单

    Public Boolean tick = false;
    private void Form1_KeyPress(object sender, KeyPressEventArgs e)
    {
    tick = !tick;
        label1.Text = "Key Pressed: " + e.KeyChar;
       //animate(sender, e);
    if(tick)
        timer1.Start();
    else
        timer1.Stop();
    }
    

    【讨论】:

    • @user3206911 你检查了吗
    【解决方案3】:

    首先,我建议您使用 keyDown 和 keyUp 事件而不是按键。要解决您的问题:在 keyDown 上简单地设置 bool = true,在 keyUp 上设置 bool = false。现在您可以检查您的 tick 方法中的 bool 并在检测到按键被按下时执行任何您想做的事情。

    【讨论】:

    • 我按照你的建议做了,看起来 Up 和 Down 事件应该可以完成这项工作。现在我删除了 Thread.Sleep(1);声明并用布尔值检查替换它,它可以工作。但问题是现在标签以非常快的速度下降,几乎不可能看到它们所代表的文本。我每次迭代都使用 Thread.Sleep(1) 来控制睡眠。有没有其他方法可以减慢这个速度?
    • @user3206911 按照其他答案的建议正确使用计时器。计时器用于每 x 毫秒执行一次常规操作。在您的情况下,每个刻度 - if(bool) 由 dX (或 dY)翻译,否则 - 什么也不做 - 。并为您希望移动的速度(或 dX/dY)设置计时器的滴答频率。 (如果我理解正确的话)
    猜你喜欢
    • 2013-07-02
    • 2012-11-13
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多