Как сделать элемент управления WPF, который обновляется каждую секунду?
-
05-07-2019 - |
Вопрос
Этот вопрос похож на другой вопрос, который я задал , но тогда я хотел узнать о принудительной привязке к обновление из XAML или модели представления, в этом случае я хотел бы знать о том, как обернуть это в пользовательский WPF FrameworkElement
.
Функциональность, которая мне нужна, - это фрагмент текста, который указывает, как давно что-то произошло.
<TextBlock Text="It happened " />
<my:AgeTextBlock SinceTime="{Binding OccurredAtUtc}" />
<TextBlock Text=" ago" />
Это будет выглядеть как (например):
Это произошло 1 мин 13 с назад
У меня есть код, который преобразуется из TimeSpan
в показанную для восприятия человеком форму.
Чтобы обновлять интерфейс каждую секунду, я подумываю использовать статический DispatcherTimer
(идея из ответ Кента Бугаарта ).
Итак, вот что у меня есть:
public class AgeTextBlock : TextBlock
{
private static readonly DispatcherTimer _timer;
static AgeTextBlock()
{
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
}
public AgeTextBlock()
{
_timer.Tick += ...;
}
// How can I unsubscribe from the Tick event to avoid a memory leak?
}
Комментарий указывает на мою проблему. Я не могу понять, как бы я убрал правильно с таким подходом. Нет метода Dispose
для переопределения и удаления обработчика событий.
Каков рекомендуемый образец здесь?
Решение
Почему бы не подписаться на событие Tick в событии Loaded элемента управления и отписаться в событии Unloaded?
Другие советы
То, что TextBlock не реализует IDisposable, не означает, что вы не можете сами добавить требования к интерфейсу и реализацию. Вы можете реализовать утилизацию самостоятельно (не перекрывая ничего из базы) и избавиться от своего таймера там.
Очевидно, что вы будете нести ответственность за удаление вашего класса AgeTextBlock. Вы можете сделать это, например, в своем событии закрытия окон или что-то в этом роде.
(В противном случае, если вы будете следовать шаблону MVVM и установите свой таймер в модели представления вы можете сделать вашу модель представления идентифицируемой и просто привязать представление к значению таймера в модели представления.)
[Редактировать: Да, если подумать, я не думаю, что это должен быть пользовательский элемент управления в отличие от Winforms, в WPF нет такой необходимости в пользовательских элементах управления, вместо этого я думаю, что я бы выставил свойство таймера на своем просмотреть модель (возможно, предварительно отформатированное свойство, чтобы у вас была удобная читаемая строка) и привязать это свойство к обычному текстовому полю - без настраиваемого элемента управления - тогда я бы использовал стиль или шаблон, чтобы настроить визуальные свойства текстового поля для просмотра как я и хотел. Как это звучит?]