Добавим таймер во ViewModel

Сегодня мы разберёмся с тем, как заставить программу, написанную с применением MVVM, самостоятельно и в реальном времени обновлять данные, с которыми взаимодействует View. Основная проблема заключается в том, что таймеры из System.Windows и System.Threading создают отдельные потоки в фоне, что вызывает исключение при попытке изменения отслеживающих обновление свойств, которые связаны с UI.

Это происходит потому, что пользовательский интерфейс может редактироваться только из того потока, в котором он был создан. В этой статье мы разберём вариант с автозапуском, а также с запуском и остановкой таймера по кнопке.

Итак, для решения проблемы воспользуемся классом DispatcherTimer из System.Windows.Threading. Пример:

//MyViewModel.cs
...
using System.Windows.Threading;//Подключим пространство имён
...
DispatcherTimer timer;//Объявим поле для таймера
...
public MyViewModel() {
    StartTimer();//Запустим таймер
}
...
#region Timer
//Метод для запуска таймера
private void StartTimer()
{
    timer = new DispatcherTimer
    {
        Interval = new TimeSpan(0, 0, 30)
    };
    timer.Tick += new EventHandler(Tick);
    timer.Start();
}

private void Tick(object sender, EventArgs e)
{
    //Здесь пишем что должен делать таймер
    MessageBox.Show("It works!");
}

#endregion

Таким образом, мы запускаем таймер при инициализации MyViewModel.
Если вам нужно запускать и останавливать таймер по кнопке, создадим для этого команды:

#region Commands
//Команда старта таймера
public ICommand StartTimerCommand {get;set;}
//Команда остановки таймера
public ICommand StopTimerCommand {get;set;}
#endregion
public MyViewModel() {
    //Вместо автозапуска повесим методы на команды.
    this.StartTimerCommand = new RelayCommand(this.StartTimer);
    this.StopTimerCommand  = new RelayCommand(this.StopTimer);
}
#region Methods
...
//Допишем метод остановки таймера
public void StopTimer()
{
    if (timer != null)
    {
        timer.Stop();
        timer = null;
    }
}
#endregion

 

Надеюсь, эта статья помогла вам решить проблему. Спасибо за внимание.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.