代码之家  ›  专栏  ›  技术社区  ›  Drew Noakes

如何生成每秒更新一次的WPF控件?

  •  0
  • Drew Noakes  · 技术社区  · 15 年前

    这个问题类似于 another one I asked 但是在这种情况下,我想知道如何强制从XAML或视图模型更新绑定,在这种情况下,我想知道如何将其包装到自定义WPF中。 FrameworkElement .

    我所追求的功能是一个文本范围,它指出了事情发生的时间。

    <TextBlock Text="It happened " />
    <my:AgeTextBlock SinceTime="{Binding OccurredAtUtc}" />
    <TextBlock Text=" ago" />
    

    这将呈现为(例如):

    发生在1分13秒前

    我有从 TimeSpan 以人类可读的形式显示。

    为了让用户界面每秒更新一次,我考虑使用静态 DispatcherTimer (来自 Kent Boogaart's answer )

    所以我有:

    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 回复  |  直到 15 年前
        1
  •  4
  •   Thomas Levesque    15 年前

    为什么不在控件的已加载事件中订阅tick事件,而在已卸载事件中取消订阅?

        2
  •  2
  •   Simon P Stevens    15 年前

    仅仅因为textBlock不实现IDisposable并不意味着您不能自己添加接口需求和实现。您可以实现Dispose-Yourself(不重写基中的任何内容)和Dispose-YoursTimer。

    显然,您将负责处理您的ageTextBlock类。例如,您可以在Windows关闭事件中执行此操作。

    (或者,如果您按照 MVVM pattern ,并将计时器放在视图模型上,可以使视图模型IDisposable,并将视图绑定到视图模型上的计时器值。)

    [编辑:是的,考虑到这一点,我不认为这应该是一个自定义控件,不像WinForms,WPF不需要自定义控件,相反,我认为我将在视图模型上公开一个计时器属性(可能是一个预格式化的属性,因此您有一个可读的字符串),并将该属性绑定到一个普通的文本框-没有自定义控件然后我会使用一个样式或模板来调整文本框的视觉属性,看看我想要什么。听起来怎么样?]