在我的应用程序中,我需要一个按钮,您可以按一次,它将其状态和外观更改为按下。 1秒后,应按下按钮。
我尝试使用ToggleButton和CheckBox。但这不是我需要的。
示例:我按下按钮。矩形的颜色已更改。 1秒后,按钮被释放。
有什么建议?
更新:按钮应播放声音。如果我使用ToggleButton或CheckBox声音播放两次,因为按钮被选中两次。
我想添加的东西:考虑使用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()。
也许你可以使用间隔1000(1秒)的计时器事件?就像你按下按钮一样,启动计时器事件,当1秒钟时,释放按钮。
你最好的办法是回去使用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
}
我根据你的要求写了一个测试应用程序。我的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事件。