Where Is the Wpf Timer Control

Where is the WPF Timer control?

The usual WPF timer is the DispatcherTimer, which is not a control but used in code. It basically works the same way like the WinForms timer:

System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// code goes here
}

More on the DispatcherTimer can be found here

How do I create a timer in WPF?

In WPF, you use a DispatcherTimer.

System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0,5,0);
dispatcherTimer.Start();

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// code goes here
}

WPF C# - Timer countdown

I've figured the complete code out as such:

DispatcherTimer _timer;

public MainWindow()
{
_myTimer = new DispatcherTimer();
_myTimer.Tick += MyTimerTick;
_myTimer.Interval = new TimeSpan(0,0,0,1);
}

private void ElementFlowSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_counter = 0;
_myTimer.Stop();
_myTimer.Interval = new TimeSpan(0, 0, 0, 1);
_myTimer.Start();
}

private int _counter;
public int Counter
{
get { return _counter; }
set
{
_counter = value;
OnPropertyChanged("Counter");
}
}
private void MyTimerTick(object sender, EventArgs e)
{
Counter++;
if (Counter == 2)
{
_myTimer.Stop();
MessageBox.Show(“Reached the 2 second countdown”);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler e = PropertyChanged;
if (e != null)
{
e(this, new PropertyChangedEventArgs(propertyName));
}
}

Show a running timer in a WPF window

Here is a very basic example I threw together.

using System.Windows.Threading;

namespace BasicTimer
{
public partial class MainWindow : Window
{
DispatcherTimer t;
DateTime start;
public MainWindow()
{
InitializeComponent();
t = new DispatcherTimer(new TimeSpan(0, 0, 0, 0, 50), DispatcherPriority.Background,
t_Tick, Dispatcher.CurrentDispatcher); t.IsEnabled = true;
start = DateTime.Now;
}

private void t_Tick(object sender, EventArgs e)
{
TimerDisplay.Text = Convert.ToString(DateTime.Now - start);
}

MainWindow XAML

<Window x:Class="BasicTimer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="100" Width="200">
<Grid>
<TextBlock x:Name="TimerDisplay" HorizontalAlignment="Left"/>
</Grid>
</Window>

WPF Multiple Timer Control

its better to use just one System.Windows.Threading.DispatcherTimer with 100ms as ticks, then use Tags to determine its own interval, for example you can use

struct IntervalComparer
{
int myinterval; //the individual update interval (300ms for example)
int currentinterval;
public IntervalComparer(int myinterval)
{
this.myinterval=myinterval;
this.currentinterval=0;
}

public void TickMe()
{
currentinterval++;
}

public void ResetkMe()
{
currentinterval = 0;
}

public bool CanIUpdate()
{
return myinterval == currentinterval;
}
}

on the creation

.... Form_Loaded....
{
.....
mypanel=new Panel();
mypanel.Tag= new IntervalComparer(2); // 2 * 100ms
.....
}

.... Timer_Tick....
{
....
(mypanel.Tag as IntervalComparer).TickMe();
if((mypanel.Tag as IntervalComparer).CanIUpdate())
{
UpdateMyPanel();//your update method
(mypanel.Tag as IntervalComparer).ResetMe();
}

....
}

WPF / C# (No MVVM) Timer with Countdown Clock

You don't actually need more than a simple DispatcherTimer and a DateTime that is cyclically reset to the current time + 300 seconds.

public partial class MainWindow : Window
{
private readonly DispatcherTimer timer = new DispatcherTimer();
private DateTime endTime;

public MainWindow()
{
InitializeComponent();

timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += new EventHandler(OnTimerTick);
timer.Start();
}

private void OnTimerTick(object sender, EventArgs e)
{
var now = DateTime.Now;

if (endTime < now)
{
endTime = now.AddSeconds(300);
}

label.Content = (endTime - now).ToString(@"mm\:ss");
}
}

How to Perfectly stop DispatcherTimer in C# WPF

You're adding a new Tick handler each time you click the Button. You may also want to check if the timer is already running before starting it again. Otherwise you would reset the interval.

Move the first two lines of btnStart_Click to a Window1 constructor:

private readonly DispatcherTimer timer = new DispatcherTimer();

public Window1()
{
timer.Interval = TimeSpan.FromMilliseconds(1000);
timer.Tick += new EventHandler(timer_Tick);
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
if (!timer.IsEnabled)
{
timer.Start();
}
}

private void btnStop_Click(object sender, RoutedEventArgs e)
{
timer.Stop();
}

private void timer_Tick(object sender, EventArgs e)
{
//data insert
}

As further improvements you could do the following:

  • enable and disable the Start and Stop Buttons according to the IsEnabled state of the timer
  • replace the two Buttons by a single ToggleButton
  • bind the ToggleButton's IsChecked property to the IsEnabled property of the timer.
  • move the timer code to a view model

Accessing form controls during Timer.Elapsed event

The System.InvalidOperationException looks like it is caused by cross-thread access to a UI component. The System.Timers.Timer by default fires the Elapsed event on a thread pool thread. Using DispatcherTimer and the Tick event will get things on the right thread for accessing the UI in WPF.

It also looks like you may have duplicate event handlers wired up, since you have both WithEvents/Handles and AddHandler, but I'm not entirely sure how that works in WPF. You probably want something like (untested):

Private attendanceFetchTimer As System.Windows.Threading.DispatcherTimer

Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
attendanceFetchTimer = New System.Windows.Threading.DispatcherTimer()
AddHandler attendanceFetchTimer.Tick, AddressOf getAllDeviceAttendance
attendanceFetchTimer.Interval = TimeSpan.FromMilliseconds(cfgAttFetchInterval)
attendanceFetchTimer.Start()
End Sub

Private Sub getAllDeviceAttendance(ByVal sender As Object, ByVal e As EventArgs)
If(checkBox1.isChecked) Then
'Do something here change the textbox value
txtStatus1.Text = "Getting Attendance Data Done!"
End If
End Sub


Related Topics



Leave a reply



Submit