Простым способом будет использование таймера (а не секундомера). Таймер - это компонент, который вы можете установить интервалы и вызвать метод для каждого тика. Объедините с элементом данных секундомера, и вы можете получить доступ к свойству Elapsed секундомера (как и в методе ShowElapsedTime) каждые 50 миллисекунд.
Основная проблема заключается в том, что таймер не совсем синхронизирован, а также будет неровным по обновлению текста ярлыка.
Другой подход - использовать поток, чтобы предотвратить блокировку пользовательского интерфейса, но если вы изменили текст метки из потока, отличного от основного потока, вы получите исключение.
Вы можете обойти это исключение, но лучшим способом будет использование BackgroundWorker.
BGWorker выполнит задачу в другом потоке, и вы можете сообщить ей о прогрессе, который будет вызываться в основном потоке.
Если вы действительно хотите быть совершенным, у вас есть класс, который реализует INotifyPropertyChanged, который имеет свойство ElapsedTime и частный член данных StopWatch. Класс будет использовать BackgroundWorker следующим образом.
В CTOR:
this._stopwatch = new Stopwatch();
this._worker = new BackgroundWorker {WorkerReportsProgress = true, WorkerSupportsCancellation = true};
_worker.DoWork += (s, e) =>
{
while (!_worker.CancellationPending)
{
_worker.ReportProgress(0, watch.Elapsed);
Thread.Sleep(1);
}
};
_worker.ProgressChanged += (s, e) =>
{
this.ElapsedTime = (TimeSpan)e.UserState;
};
Если вы хотите, чтобы начать рабочий (он же запустить таймер):
stopwatch.Start();
_worker.RunWorkerAsync();
И если вы хотите, чтобы остановить рабочий (он же остановить таймер) :
stopwatch.Reset();
_worker.CancelAsync();
У самого класса будут методы «Старт и Стоп», которые будут взаимодействовать с работником (членом данных).
Наконец, вы можете НАПРАВИТЬ текст метки в свой класс ElapsedTime. Или подписаться на событие ElapsedTimeChanged с помощью метода ShowElapsedTime, за исключением того, что вместо него будет использоваться свойство ElapsedTime вашего класса, а не свойство stopWatch.Elapsed.
Нет ли вызов таймера остановки требуется? не будет ли это вечно? – batmaci
OP спрашивал, как отображать время на ярлыке, поэтому мой ответ был сфокусирован на этом. Когда условие остановки достигнуто для активности (нажатие кнопки, ввод пользователя и т. Д.), Вам необходимо сделать вызов таймера.Stop() https://msdn.microsoft.com/en-us/library/system.windows .threading.dispatchertimer.stop (v = vs.110) .aspx –
Спасибо за разъяснение. ваш код тоже помог мне, но я хотел бы привязать его к другой viewmodel, которая является datacontext моего представления. Можете ли вы дать мне подсказку, как я могу связать их обоих? Так что, хотя datagrid связан другой наблюдаемой моделью viewmodel, я могу активировать таймер в качестве секций загрузки, точно так же, как таймер в студии управления SQL SQL при выполнении запроса. Если это так сложно, я открою новый поток. большое спасибо. – batmaci