C# — countdown timer with periodical ticks + Xamarin.Forms binding helper + Basic usage example

Alexey Kinev
2015-01-11T16:08:03Z

Countdown.cs

| //
| // Countdown.cs
| // Created by Alexey Kinev on 11 Jan 2015.
| //
| // Licensed under The MIT License (MIT)
| // http://opensource.org/licenses/MIT
| //
| // Copyright (c) 2015 Alexey Kinev <alexey.rudy@gmail.com>
| //
| using System;
| using System.ComponentModel;
| using System.Runtime.CompilerServices;
| using System.Timers;
|
| namespace ZeroFiveBit.Utils
| {
| ///
| /// Countdown timer with periodical ticks.
| ///
| public class Countdown : INotifyPropertyChanged
| {
| ///
| /// Gets the start date time.
| ///
| public DateTime StartDateTime { get; private set; }
|
| ///
| /// Gets the remain time in seconds.
| ///
| public double RemainTime
| {
| get { return remainTime; }
|
| private set
| {
| remainTime = value;
| OnPropertyChanged();
| }
| }
|
| ///
| /// Occurs when completed.
| ///
| public event Action Completed;
|
| ///
| /// Occurs when ticked.
| ///
| public event Action Ticked;
|
| ///
| /// The timer.
| ///
| Timer timer;
|
| ///
| /// The remain time.
| ///
| double remainTime;
|
| ///
| /// The remain time total.
| ///
| double remainTimeTotal;
|
| ///
| /// Starts the updating with specified period, total time and period are specified in seconds.
| ///
| public void StartUpdating(double total, double period = 1.0)
| {
| if (timer != null)
| {
| StopUpdating();
| }
|
| remainTimeTotal = total;
| RemainTime = total;
|
| StartDateTime = DateTime.Now;
|
| timer = new Timer(period * 1000);
| timer = new Timer();
| timer.Elapsed += (sender, e) => Tick();
| timer.Enabled = true;
| }
|
| ///
| /// Stops the updating.
| ///
| public void StopUpdating()
| {
| RemainTime = 0;
| remainTimeTotal = 0;
|
| if (timer != null)
| {
| timer.Enabled = false;
| timer = null;
| }
| }
|
| ///
| /// Updates the time remain.
| ///
| public void Tick()
| {
| var delta = (DateTime.Now - StartDateTime).TotalSeconds;
|
| if (delta < remainTimeTotal)
| {
| RemainTime = remainTimeTotal - delta;
|
| var ticked = Ticked;
| if (ticked != null)
| {
| ticked();
| }
| }
| else
| {
| RemainTime = 0;
|
| var completed = Completed;
| if (completed != null)
| {
| completed();
| }
| }
| }
|
| #region INotifyPropertyChanged implementation
|
| ///
| /// Occurs when property changed.
| ///
| public event PropertyChangedEventHandler PropertyChanged;
|
| ///
| /// Raises the property changed event.
| ///
| private void OnPropertyChanged([CallerMemberName] string propertyName = null)
| {
| var handler = PropertyChanged;
| if (handler != null)
| {
| handler(this, new PropertyChangedEventArgs(propertyName));
| }
| }
|
| #endregion
| }
| }
|

CountdownConverter.cs

| //
| // CountdownConverter.cs
| // Created by Alexey Kinev on 11 Jan 2015.
| //
| // Licensed under The MIT License (MIT)
| // http://opensource.org/licenses/MIT
| //
| // Copyright (c) 2015 Alexey Kinev <alexey.rudy@gmail.com>
| //
| using System;
| using Xamarin.Forms;
|
| namespace ZeroFiveBit.Utils
| {
| ///
| /// Converts countdown seconds double value to string "HH : MM : SS"
| ///
| public class CountdownConverter : IValueConverter
| {
| #region IValueConverter implementation
|
| public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
| {
| var timespan = TimeSpan.FromSeconds((double)value);
|
| if (timespan.TotalSeconds < 1.0)
| {
| return "-- : --";
| }
| // else if (timespan.TotalSeconds < 3600)
| // {
| // return string.Format("{0:D2} : {1:D2}",
| // timespan.Minutes, timespan.Seconds);
| // }
| else if (timespan.TotalSeconds > 3600 * 24)
| {
| return "24 : 00 : 00";
| }
|
| return string.Format("{0:D2} : {1:D2} : {2:D2}",
| timespan.Hours, timespan.Minutes, timespan.Seconds);
| }
|
| public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
| {
| throw new NotImplementedException();
| }
|
| #endregion
| }
| }
|
|

CountdownExample.cs

| //
| // CountdownExample.cs
| // Created by Alexey Kinev on 11 Jan 2015.
| //
| // Licensed under The MIT License (MIT)
| // http://opensource.org/licenses/MIT
| //
| // Copyright (c) 2015 Alexey Kinev <alexey.rudy@gmail.com>
| //
| using System;
| using Xamarin.Forms;
| using ZeroFiveBit.Utils;
|
| namespace CountdownExample
| {
| public class App
| {
| static Countdown countdown;
|
| public static Page GetMainPage()
| {
| var label = new Label
| {
| Text = "Hello, Forms!",
| VerticalOptions = LayoutOptions.CenterAndExpand,
| HorizontalOptions = LayoutOptions.CenterAndExpand,
| };
|
| countdown = new Countdown();
| countdown.StartUpdating(3600 * 24);
|
| label.SetBinding(Label.TextProperty,
| new Binding("RemainTime", BindingMode.Default, new CountdownConverter()));
| label.BindingContext = countdown;
|
| return new ContentPage
| {
| Content = label,
| };
| }
| }
| }
|