x秒后释放按钮

时间:2018-03-05 14:25:28

标签: c# wpf xaml

在我的应用程序中,我需要一个按钮,您可以按一次,它会将其状态和外观更改为按下。 1秒后,应按下按钮。

我尝试使用ToggleButton和CheckBox。但这不是我需要的。

实施例: 我按下按钮。矩形的颜色已更改。 1秒钟后,按钮被释放。

有什么建议吗?

更新:按钮应播放声音。如果我使用ToggleButton或CheckBox声音播放两次,因为按钮被选中两次。

4 个答案:

答案 0 :(得分:1)

我想添加的东西:考虑使用Task而不是Timer。一方面,这意味着您不必在DispatchTimer之后进行清理并停止它;从消极方面来说,这意味着您需要在GUI对象上使用Invoke()而不是直接更改它(因为它将从非gui线程运行。)

这里有一些简单的代码,只是暂时按钮禁用/启用来说明:

private void btnTest_Click(object sender, EventArgs e)
{
    btnTest.Enabled = false;
    Task t = new Task(async () =>  { await Task.Delay(2000); EnableButton(); });
    t.Start();
}
private void EnableButton()
{
    btnTest.Invoke((MethodInvoker)delegate { btnTest.Enabled = true; });
}

编辑:更改为使用Task.Delay而不是Thread.Sleep()。

答案 1 :(得分:0)

也许您可以使用间隔为1000(1秒)的计时器事件? 就像你按下按钮一样,启动计时器事件,当1秒钟时,释放按钮。

答案 2 :(得分:0)

您最好的选择是返回并使用ToggleButton,但在1秒后重置它。这就是它的用途。为您的ToggleButton创建一个click事件,并创建一个DispatcherTimer来处理延迟的切换。

    //Reference
    using System.Windows.Timers;

    //Toggle Button Click Event
    private void button_Click(object sender, RoutedEventArgs e)
    {
        button.IsChecked = true;

        //Create New DispatcherTimer
        DispatcherTimer dst = new DispatcherTimer();
        dst.Interval = new TimeSpan(0, 0, 1);  //Set Interval to 1 second.       
        dst.Tick += Dst_Tick;                   
        dst.Start(); //Start Timer  
    }

    //Timer Elapsed Event
    private void Dst_Tick(object sender, EventArgs e)
    {
        DispatcherTimer t = (DispatcherTimer)sender; //Grab the DispatcherTimer
        t.Stop(); //Stop the timer or it will keep looping
        button.IsChecked = false; //Reset the ToggleButton          
    }

答案 3 :(得分:0)

我根据您的要求编写了一个测试应用程序。 我的Xaml文件如下所示

<Window x:Class="toggleButtonTimer.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:toggleButtonTimer"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel>
        <TextBlock x:Name="_value"></TextBlock>
        <ToggleButton Width="100" Height="100" x:Name="_toggle" Click="_toggle_Click" IsChecked="False"></ToggleButton>
    </StackPanel>
</Grid>

背后的代码如下(修改了Tronald的代码......)

    using System;
    using System.Windows;
    using System.Windows.Threading;
 ....


    private int value = 0;
    private void _toggle_Click(object sender, RoutedEventArgs e)
    {
        _toggle.IsChecked = true;

        //Create New DispatcherTimer
        DispatcherTimer dst = new DispatcherTimer();
        dst.Interval = new TimeSpan(0, 0, 1);  //Set Interval to 1 second.       
        dst.Tick += Dst_Tick;
        dst.Start(); //Start Timer  

        value++;
        _value.Text = value.ToString();
    }

    //Timer Elapsed Event
    private void Dst_Tick(object sender, EventArgs e)
    {
        DispatcherTimer t = (DispatcherTimer)sender; //Grab the DispatcherTimer
        t.Stop(); //Stop the timer or it will keep looping
        _toggle.IsChecked = false; //Reset the ToggleButton    

        value--;
        _value.Text = value.ToString();
    }

每次点击时,TextBlock会对变量计数+1,当计时器过去时,它会计数-1。所以textBlock在一个循环后保持为0。这对我来说很好。因为结尾的结果是0.所以事件只处理一次。

它适用于点击事件和已检查事件。