想要一个按钮在单击后禁用30秒并自动启用它

时间:2013-12-21 10:28:48

标签: c# wpf multithreading

我正在进行一个项目,这个项目需要从random.org中随机取16个字节。我可以从网站上获取它并将这16个字节写入textedit。我也有一个刷新按钮。每次单击此按钮时,都会出现新的16字节,并以textedit编写。

我想阻止用户按顺序单击刷新按钮。我想要的是在点击后禁用刷新按钮。但是,我想要的另一件事是在30秒后自动启用此按钮。

我在按钮点击事件中尝试thread.sleep(30000),但它会使整个程序停止30秒。我想禁用刷新按钮30秒,而不是程序的其余部分。

我想向用户展示一种秒表,以便他们可以看到他们应该等待下次点击的时间。例如,在他们点击刷新按钮后,会出现这个30秒的秒表。

7 个答案:

答案 0 :(得分:12)

如果我们在这里谈论WPF,有一种方法可以在没有任何代码隐藏的情况下使用EventTriggers实现所需的行为:

 <Style TargetType="Button">

        <Style.Triggers>

            <EventTrigger RoutedEvent="Button.Click">

                <EventTrigger.Actions>

                    <BeginStoryboard>

                        <Storyboard>

                            <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled">

                                <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />

                                <DiscreteBooleanKeyFrame KeyTime="00:00:30" Value="True" />

                            </BooleanAnimationUsingKeyFrames>

                        </Storyboard>

                    </BeginStoryboard>

                </EventTrigger.Actions>

            </EventTrigger>

        </Style.Triggers>

    </Style>

答案 1 :(得分:5)

尝试这样的事情:

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
private void button1_Click(object sender, EventArgs e)  // event handler of your button
{                
    timer.Interval = 30000; // here time in milliseconds
    timer.Tick += timer_Tick;
    timer.Start();
    button1.Enabled = false;

    // place get random code here
}

void timer_Tick(object sender, System.EventArgs e)
{
    button1.Enabled = true;
    timer.Stop();
}

答案 2 :(得分:0)

尝试使用计时器并在勾选后启用按钮。 有关详细信息:http://www.dotnetperls.com/timer

答案 3 :(得分:0)

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
timer1.Interval=1000;//one second
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Start();
int count=30;
private void timer1_Tick(object sender, EventArgs e)
{
   if(count!=0)
   {
   button1.Enabled=false;
   label1.Text =  count.ToString() +" seconds more to Enable Refresh Button";
   count--;
   }
   else
   {
   button1.Enabled=true;
   timer1.Stop();
   }

}

答案 4 :(得分:0)

使用计时器 有一个片段来创建计时器 http://dotnet-snippets.de/snippet/timer-anlegen/111

在按钮上单击按钮禁用按钮并启动计时器。在勾选中启用按钮并停止计时器。

答案 5 :(得分:0)

根据user2737037的回答,这是一种讨厌的代码隐藏方法。

通过这种方式,您无需声明任何成员字段即可保持代码整洁。

private void btnFoo_Click(object s, RoutedEventArgs e)
{
    var btn = (Button)sender;
    btn.IsEnabled = false; //Disable button.
    var fooTimer = new System.Timers.Timer(5000); //Exceute after 5000 milliseconds
    timer.Elapsed += (fooTimer_s, fooTimer_e) => 
    {
        //It has to be dispatched because of thread crossing if you are using WPF.
        Dispatcher.Invoke(()=>  
        {
            btn.IsEnabled = true; //Bring button back to life by enabling it.
            fooTimer.Dispose();
        });
    };
    fooTimer.Start();

    //Insert your code here :)
}

答案 6 :(得分:0)

从C#5.0开始,您可以使用async/awaitTask.Delay在方法中间等待30秒,而不会阻塞UI线程:

private async void YourButton_Click(object sender, EventArgs e)
{
    UIElement element = (UIElement)sender;

    element.IsEnabled = false;
    await Task.Delay(30000); // 30 seconds
    element.IsEnabled = true;
}