Как сделать элемент управления WPF, который обновляется каждую секунду? - PullRequest
0 голосов
/ 16 июня 2009

Этот вопрос похож на другой вопрос, который я задал , но тогда как в этом случае я хотел знать о принудительной привязке к обновлению из 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 метода для переопределения и удаления обработчика событий.

Какой рекомендуемый шаблон здесь?

Ответы [ 2 ]

4 голосов
/ 16 июня 2009

Почему бы не подписаться на событие Tick в событии Loaded элемента управления и отписаться в событии Unloaded?

2 голосов
/ 16 июня 2009

То, что TextBlock не реализует IDisposable, не означает, что вы не можете сами добавить требования к интерфейсу и реализацию. Вы можете реализовать утилизацию самостоятельно (не перекрывая ничего из базы) и избавиться от своего таймера там.

Очевидно, что вы будете нести ответственность за удаление вашего класса AgeTextBlock. Вы можете сделать это, например, в своем событии закрытия окон или что-то в этом роде.

(С другой стороны, если вы следуете шаблону MVVM и поместите свой таймер в модель представления, вы можете сделать модель представления ID доступной и просто привязать представление к значению таймера в модели представления.)

[Edit: Да, если подумать, я не думаю, что это должен быть пользовательский элемент управления в отличие от Winforms, в WPF нет такой необходимости в пользовательских элементах управления, вместо этого я думаю, что я бы выставил свойство таймера на моем просмотреть модель (возможно, предварительно отформатированное свойство, чтобы у вас была удобная читаемая строка) и привязать это свойство к обычному текстовому полю - без настраиваемого элемента управления - тогда я бы использовал стиль или шаблон, чтобы настроить визуальные свойства текстового поля для просмотра как я и хотел. Как это звучит?]

...