0

这个问题与我问的另一个问题相似,但是在那种情况下,我想知道强制绑定从 XAML 或视图模型更新,在这种情况下,我想知道如何将其包装到自定义 WPFFrameworkElement中。

我所追求的功能是一段文本,表明某件事发生了多久。

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

这将呈现为(例如):

发生在 1 分 13 秒前

我有从 a 转换为TimeSpan显示的人类可读形式的代码。

为了让 UI 每秒更新一次,我正在考虑使用静态DispatcherTimer(来自Kent Boogaart 的回答的想法)。

所以这就是我所拥有的:

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方法可以覆盖和删除事件处理程序。

这里推荐的模式是什么?

4

2 回答 2

4

为什么不在控件的Loaded事件中订阅Tick事件,在Unloaded事件中取消订阅呢?

于 2009-06-16T12:12:49.477 回答
2

仅仅因为 TextBlock 没有实现 IDisposable 并不意味着您不能自己添加接口要求和实现。您可以自己实现 dispose (不覆盖基础中的任何内容)并在那里处理您的计时器。

您显然将负责处理您的 AgeTextBlock 类。例如,您可以在关闭窗口的事件中执行此操作或类似的操作。

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

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

于 2009-06-16T11:46:50.013 回答