Reputation: 287
In my application I need a button that you can press once and it changes its state and appearance to pressed. After 1 seconds the pressed button should be released.
I tried doing that with ToggleButton and CheckBox. But this is not what I need.
EXAMPLE: I press the Button. Color of a rectangle is changed. After 1 second the Button is released.
Any suggestions?
UPDATE: The button should play a sound. If I use ToggleButton or CheckBox that sound is played twice, because the button is checked two times.
Upvotes: 1
Views: 802
Reputation: 2243
Something I wanted to add: consider using Task instead of a Timer. One the plus side, it means you don't have to clean up after a DispatchTimer and stop it; on the negative side, it means you need to use Invoke() on the GUI object instead of changing it directly (because it'll be running from the non-gui thread.)
Here's some simple code that just does a momentary button disable/enable to illustrate:
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; });
}
EDIT: changed to use Task.Delay instead of Thread.Sleep().
Upvotes: 2
Reputation: 145
i wrote a test application with your requirement. my Xaml file looks like following
<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>
Code behind is as follows (modified the code from 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();
}
The TextBlock counts +1 the variable everytime click is fired and when the timer elapses, it counts -1. So the textBlock stays 0 after a cycle. This works fine for me. Because the result at the end is 0. So the event is processed only once.
It worked both for Click event and the Checked event.
Upvotes: 0
Reputation: 1585
Your best bet is to go back and use the ToggleButton, but reset it after 1 second. That is what it's for. Create a click event for your ToggleButton and the make a DispatcherTimer to handle the delayed toggle.
//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
}
Upvotes: 0
Reputation: 1
Maybe you could use a timer event with interval 1000 (1 second)? Like you press the button, fire up the timer event and when 1 second passes release the button.
Upvotes: 0