首页 > 解决方案 > 全球秒表 WPF - 如何/为什么这不起作用

问题描述

假设我有 2 个 Windows(loginWindowMainWindow)。当某个时间用完(比如说 30 秒)时,我希望我的程序再次自动记录(打开loginWindow)。我试图编写一个全局秒表,我可以在我的程序中从我想要的任何地方重置,这样我就可以在时间用完后打开loginWindow。这就是我得到的:(我对 WPF 也很陌生)

全球类:

  public static Stopwatch stopwatch = new Stopwatch();
  public static long timeSpan;


    public static void startStopwatch()
    {
        stopwatch.Start();
        Thread.Sleep(10000);
        stopwatch.Stop();
        Console.WriteLine(stopwatch.ElapsedMilliseconds);
        timeSpan = stopwatch.ElapsedMilliseconds / 1000;

    }

    public static void restartStopwatch()
    {
        stopwatch.Stop();
        startStopwatch();
    }

第 1 页(主窗口):

     public Page1()
    {
        InitializeComponent();
        GlobalClass.startStopwatch();
        if(GlobalClass.timeSpan == 10)
        {
            MessageBox.Show("Stopwatch reached end"); //also jump back to loginWindow
        }

    }

所以这不起作用,但我不知道为什么。我的问题是:在我更多地进入秒表之前,我应该用秒表解决这个问题还是使用不同的方式来实现我想要的。还有为什么这不起作用:(。

提前感谢<3

标签: c#wpfmvvmstopwatch

解决方案


您可以将计时器实现为 Singelton,并将导航处理程序(或您的导航概念)注册到 TickEvent。当您设置的时间到期时触发该事件,您可以返回登录屏幕。

您现在可以从不同的位置开始/停止/重置。

public class GlobalTimer : Timer
{
    private GlobalTimer instance;

    public GlobalTimer Instance => instance ?? (instance = new GlobalTimer());

    private GlobalTimer()
    {
    }
}

编辑:StopWatch,顾名思义,是一个测量时间跨度的类。你想要的更像是一个闹钟,它会在特定时间过去时通知你。

您的程序无法运行,因为您正在等待 UI 创建。这意味着 UI 尚未绘制,您告诉正在绘制的线程等待 10 秒,然后再次绘制前一个。因此不显示第 1 页。因此永远不要Thread.wait(x)在 UI 线程中(当线程不工作(睡眠)时,您的 UI 会冻结)。

这是 Timer 类的链接,以了解 Timer 如何工作的更多信息:https ://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

编辑 2:正如 Clemens 所说,DispatcherTimer 是 UI 应用程序的更好选择,因为事件是通过 UI 线程处理的。如果您想使用“普通”计时器,您可能必须使用调度程序调用 UI 元素(变量/Methoen/等)。否则数据将在不工作的不同线程中管理。

在此处查看答案/更多信息:WPF - 线程和更改变量


推荐阅读