x秒后释放按钮

问题描述 投票:0回答:4

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

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

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

有什么建议?

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

c# wpf xaml
4个回答
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()。


0
投票

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


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          
    }

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.所以事件只处理一次。

它适用于Click事件和Checked事件。

© www.soinside.com 2019 - 2024. All rights reserved.