Creando un cronómetro para Windows Phone

Nuevamente por acá luego de una (demasiado larga) ausencia por motivos laborales, y hoy voy a empezar con una serie de artículos en los que desarrollaré un cronómetro para Windows Phone, esto es, una aplicación que nos permita medir el tiempo transcurrido desde cierto momento. Esta idea surge como una solicitud en una charla que tuve hace alrededor de 1 mes en la Universidad de Los Andes en Mérida – Venezuela y en la misma surgió esta necesidad, si bien en el momento de la charla no se contaba con el tiempo suficiente para desarrollar por completo la idea ahora sí lo haré.

En principio la aplicación implementará una funcionalidad básica pero será suficiente para demostrar el principio de un temporizador, mi idea fundamental ahora es desarrollar un cronómetro como los que utilizan los entrenadores para llevar los tiempos parciales y el tiempo total transcurridos durante cierta actividad física pero con la precisión establecida en segundos, sin embargo, este mismo componente se podría utilizar para llevar el tiempo en un juego, así que trabajaremos con una biblioteca de clases para poder reutilizar luego el componente.

Este proyecto se realizará utilizando la plantilla de «Biblioteca de Clases de Windows Phone».

Para cumplir con el objetivo haremos en principio un diseño de la estructura de datos que necesitamos, básicamente almacenaremos las horas, los minutos y los segundos transcurridos desde que se inicia el temporizador del evento y obviamente, también necesitaremos este «temporizador» así como se ve en el siguiente código:

private int seconds;
private int minutes;
private int hours;
private DispatcherTimer timer;

Recordemos que DispatcherTimer está en el Namespace System.Windows.Threading por lo cual es necesario agregar la correspondiente instrucción using.

Una vez que definimos los campos que necesitamos, debemos implementar en la clase la interfaz INotifyPropertyChanged ya que queremos soportar en enlace de datos y eventualmente MVVM, dicha interfaz se encuentra en el Namespace System.ComponentModel y es necesario agregar la instrucción using correspondiente.

public class TimeCounter : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    ...
}

Definiremos unas propiedades que hagan uso de los campos en donde se almacenarán los valores correspondientes, como debemos recordar, 60 segundos es 1 minuto y 60 minutos es 1 hora, así que teniendo eso en cuenta implementaremos lo siguiente:

public int Seconds
{
    get
    {
        return seconds;
    }
    set
    {
        seconds = value;
        if (seconds >= 60)
        {
            Minutes += (seconds / 60);
            Seconds %= 60;
        }
        NotifyPropertyChanged("Seconds");
    }
}

public int Minutes
{
    get
    {
        return minutes;
    }
    set
    {
        minutes = value;
        if (minutes >= 60)
        {
            Hours += (minutes / 60);
            Minutes %= 60;
        }
        NotifyPropertyChanged("Minutes");
    }
}

public int Hours
{
    get
    {
        return hours;
    }
    set
    {
        hours = value;
        NotifyPropertyChanged("Hours");
    }
}

Bien como notarás el IDE nos indica que «NotifyPropertyChanged» no está implementado y ese método lo implementaremos de la siguiente forma:

private void NotifyPropertyChanged(String propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Ya estamos casi listos, ahora sólo nos queda implementar las correspondientes inicializaciones en el constructor de la clase como sigue:

public TimeCounter()
{
    timer = new DispatcherTimer();
    timer.Interval = new TimeSpan(0, 0, 1);
    timer.Tick += (t, a) => { AddSeconds(1); };
    Reset();
}

En el código anterior se establece el intervalo del temporizador en 1 segundo, es decir, cada segundo se disparará el evento Tick y a dicho evento le asignamos mediante uso de expresiones Lambda, una función que se encarga de sumar 1 segunda al tiempo transcurrido y finalmente se «restauran» los valores de hours, minutes y seconds, es decir, se colocan en cero.

Y ahora para finalizar agregamos los métodos necesarios para iniciar/detener el temporizador, agregar segundos, minutos u horas al tiempo transcurrido y restaurar los valores mediante el siguiente código:

public void AddSeconds(int seconds)
{
    Seconds += seconds;
}

public void AddMinutes(int minutes)
{
    Minutes += minutes;
}

public void AddHours(int hours)
{
    Hours += hours;
}

public void Reset()
{
    Seconds = 0;
    Minutes = 0;
    Hours = 0;
}

public void Start()
{
    if (timer == null)
        return;
    timer.Start();
}

public void Stop()
{
    if (timer == null)
        return;
    timer.Stop();
}

Del código anterior es importante destacar que se debe verificar que el temporizador (timer) no es nulo (timer != null) antes de realizar cualquier operación con el mismo puesto que es posible que se haga llamado al método antes de que se haya inicializado el objeto y obtendríamos una excepción en la aplicación.

Con esto concluimos la implementación del componente y podemos probarlo creando un proyecto de prueba, cosa que haré en la próxima entrega.

Acá les dejo el archivo compilado TimeCounterWP71 si tienes alguna duda, comentario o corrección no dudes en contactarme. El componente de software se provee tal cual sin ningún tipo de garantía y el autor no se hace responsable por cualquier daño que pueda ocurrir por el uso del producto, use bajo su propia responsabilidad. El uso del componente en forma personal o  comercial está permitido, en el caso de esta última se debe agregar al producto una nota que indique el uso del componente y el autor del mismo. Un email notificándome de su uso sería un gran adicional.

5 pensamientos en “Creando un cronómetro para Windows Phone

  1. Pingback: Creando un cronómetro para Windows Phone parte 2 | Interoperando ando...