wpf - 绑定(bind)到时间相关的属性

标签 wpf data-binding time dependencies notifications

前段时间我写了一个类似小部件的应用程序,它应该跟踪任务,每个任务都有一个指定为 DateTime 的截止日期。 ,现在如果您想显示距离截止日期还有多长时间,您可能希望绑定(bind)到“虚拟”(*诅咒 virtual 关键字*)属性,如下所示:

public TimeSpan TimeLeft
{
    get { return Deadline - DateTime.Now; }
}

显然,理论上这个属性在每一次滴答声中都会发生变化,并且您希望时不时地更新您的 UI(例如,通过定期为该属性抽出 PropertyChanged 事件)。

回到我写小部件时,我每分钟刷新整个任务列表,但这并不理想,因为如果用户与某些项目交互(例如,通过键入绑定(bind)到 Comments -property 的 TextBox)将被严重中断并且对源的更新会丢失。

那么,如果您有这样的时间相关属性,那么更新 UI 的最佳方法可能是什么?

(顺便说一句,我不再使用该应用程序,只是认为这是一个非常有趣的问题)

最佳答案

计时器是我能想到的唯一方法。由于这是一个有趣的问题,我将把我的 .02 放进去。我会像这样封装它:

public class CountdownViewModel : INotifyPropertyChanged
{
    Func<TimeSpan> calc;
    DispatcherTimer timer;

    public CountdownViewModel(DateTime deadline)
        : this(() => deadline - DateTime.Now)
    {
    }

    public CountdownViewModel(Func<TimeSpan> calculator)
    {
        calc = calculator;

        timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += timer_Tick;
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        var temp = PropertyChanged;
        if (temp != null)
        {
            temp(this, new PropertyChangedEventArgs("CurrentValue"));
        }
    }

    public TimeSpan CurrentValue
    {
        get
        {
            var result = calc();
            if (result < TimeSpan.Zero)
            {
                return TimeSpan.Zero;
            }
            return result;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class MyViewModel
{
    public CountdownViewModel DeadlineCountdown { get; private set; }

    public DateTime Deadline { get; set; }

    public MyViewModel()
    {
        Deadline = DateTime.Now.AddSeconds(200);
        DeadlineCountdown = new CountdownViewModel(Deadline);
    }
}

然后你可以绑定(bind)到 DeadlineCountdown.CurrentValue直接,或创建一个CountdownView .您可以将计时器移至 CountdownView ,如果你愿意。您可以使用静态计时器,以便它们同时更新。

编辑

如果 Deadline将会改变,你必须像这样构建倒计时:
DeadlineCountdown = new CountdownViewModel(() => this.Deadline - DateTime.Now);

关于wpf - 绑定(bind)到时间相关的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6123998/

相关文章:

c# - 使图像变亮/变暗/透明部分

c# - 更新 "live"WPF Canvas (折线),当 PointCollection 发生变化时

wpf - 将 Wpf HierarchicalDataTemplate ItemsSource 绑定(bind)到字典中的 CollectionViewSource?

c++ - 如何从日期中减去时间

c# - 在 WPF 中限制 "Auto"和 "1*"上的行高

wpf - PowerShell WPF 数据网格 : Exception thrown committing empty row

javascript - SPA 中的 ID 空间

java - 将 Label 的文本属性(在 FXML 文件中)绑定(bind)到 IntegerProperty(在 Controller 中)

MySQL - CET 和 CEST 之间的区别

mysql - 检查时间重叠表?