使用WPF MVVM实施和显示UI计时器

jrandomuser

我有一个显示各种警报和状态的应用程序。某些警报在跳闸时应该显示一个计时器,该计时器从被激活的时间开始计时。我已经阅读了几种实现方法,甚至在这里都对SO提出了疑问,但似乎没有任何方法可以100%地起作用。

以下解决方案是最接近的。计时器显示并更新,但大约每30至45秒更新1秒。UI属性绑定到TimeElapsed属性,设置TimeStarted属性将启动所有操作。

 public class Alarm : INotifyPropertyChanged
 {
    DispatcherTimer timer = null;
    Stopwatch stopWatch = new Stopwatch();

    public Alarm()
    {
        Application.Current.Dispatcher.Invoke(() =>
        { 
            timer = new DispatcherTimer();
            timer.Tick += timer_Tick;
            timer.Interval = new TimeSpan(0, 0, 1);

        }, DispatcherPriority.Normal); 
    }

    private TimeSpan initialDifference;
    private DateTime? timeStarted;
    public DateTime? TimeStarted
    {
        get { return timeStarted; }
        set
        {
            // If the value is new
            if (timeStarted != value)
            {
                // If timeStarted was previously null then start the new timer
                if (!timeStarted.HasValue)
                {
                    timeStarted = value;

                    // Get the initial difference between Now and TimeStarted
                    initialDifference = DateTime.Now.Subtract(TimeStarted.Value);

                    //irolTimer = new System.Threading.Timer(TickTick, null, 1000, 1000);

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        stopWatch.Start();
                        timer.Start(); 
                    }, DispatcherPriority.Normal);

                }
                // If the timeStarted had a value but now its gone (stop the timer)
                else if (timeStarted.HasValue && value == null)
                {
                    if (stopWatch.IsRunning)
                        stopWatch.Stop();

                    timeStarted = value;
                }
                // If we already have a timer going but for some reason we just received a different start time
                else if (timeStarted.HasValue && value != null)
                {
                    timeStarted = value;

                    // Change the initial difference
                    initialDifference = DateTime.Now.Subtract(TimeStarted.Value);
                } 

                OnPropertyChanged("TimeStarted");
            }
        }
    }

    private string timeElapsed = string.Empty;
    public string TimeElapsed
    {
        get
        {
            return timeElapsed;
        }
        set
        {
            timeElapsed = value;
            OnPropertyChanged("TimeElapsed");
        }
    }

    void timer_Tick(object sender, EventArgs e)
    { 
        if (stopWatch.IsRunning)
        {
            TimeSpan elapsed = stopWatch.Elapsed;
            TimeSpan total = initialDifference + elapsed;

            TimeElapsed = String.Format("{0:00}:{1:00}:{2:00}", total.Hours, total.Minutes, total.Seconds / 10); 
        }
    }

 }

将Dispatcher.Invoke添加到Tick事件中会使计时器完全不显示。我尝试了几种不同的实现,包括使用没有运气的常规System.Threading.Timer。StopWatch似乎有些过分,我认为我可以通过以下操作完成相同的操作,但导致其停止工作:

  TimeElapsed = DateTime.Now.Subtract(TimeStarted.Value).ToString("hh:mm:ss");

这是一个屏幕截图,出于安全方面的考虑,我不得不对其进行编辑,但是我尝试将Text添加回上下文。用红色圈出的项目是计时器的文本。Xaml很简单,如下所示:

<StackPanel DockPanel.Dock="Left">
     <TextBlock FontSize="18" Text="{Binding Path=DisplayName, IsAsync=True}" Style="{StaticResource Alarm}" Foreground="White" FontWeight="Bold"  Padding="2,2,2,2" />
     <TextBlock Text="{Binding Path=TimeElapsed, IsAsync=True}" Foreground="White" FontSize="12" FontWeight="Bold" />   
 </StackPanel>

在此处输入图片说明

亚当·罗兹

您的代码应该可以正常工作。为了确保我将其放入一个空的WPF项目中,并使用简单的数据模板创建了一个简单的警报列表,它可以按预期工作。

我确实注意到的一件事是,您对经过的秒数进行了整数除法,如下所示:

TimeElapsed = String.Format("{0:00}:{1:00}:{2:00}", total.Hours, total.Minutes, total.Seconds / 10);

这将导致TimeElapsed属性仅每10秒更新一次,因为字符串直到总秒数到达下一个因子10才改变。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用WPF MVVM实施和显示UI计时器

来自分类Dev

从计时器线程更新WPF UI

来自分类Dev

在MVVM-WPF中更新DataContext的计时器

来自分类Dev

在WPF窗口中显示正在运行的计时器

来自分类Dev

WPF计时器+显示窗口出错

来自分类Dev

设置并显示使用js和php的表单的倒数计时器

来自分类Dev

计时器-如何使用计时器以一定间隔显示文本?

来自分类Dev

如何使用PyQt5 for Python显示计时器

来自分类Dev

使用计时器的Javascript幻灯片显示

来自分类Dev

如何在计时器中使用异步和等待

来自分类Dev

如何使用onModuleLoad()和计时器加载页面

来自分类Dev

如何在计时器中使用异步和等待

来自分类Dev

在 Tkinter 中使用倒数计时器启动和暂停

来自分类Dev

WPF C#-计时器倒数

来自分类Dev

WPF中Dispatcher计时器的性能

来自分类Dev

如何为 WPF 创建计时器

来自分类Dev

使用倒数计时器

来自分类Dev

如何在计时器(分钟秒)中显示TimerFormat WPF vb.net

来自分类Dev

使用异步管道显示基于计时器的可观察对象的显示加载指示器

来自分类Dev

使用MVVM的WPF导航

来自分类Dev

使用 UI 线程上的计时器更新标签文本,而不会阻塞 UI

来自分类Dev

WPF使用计时器动态更改图像源

来自分类Dev

如何通过准确使用调度程序计时器来控制WPF中的帧速率?

来自分类Dev

使用WPF的本机UI

来自分类Dev

使用WPF的本机UI

来自分类Dev

WPF使用计时器重复操作

来自分类Dev

WPF中分派器计时器的性能

来自分类Dev

实施WatchDog计时器

来自分类Dev

使用PHP和计时器启动和终止后台python脚本