C# 带倒计时时钟的WPF/C(无MVVM)计时器

C# 带倒计时时钟的WPF/C(无MVVM)计时器,c#,wpf,timer,C#,Wpf,Timer,大家好, 我正在努力解决一个编码问题,我需要一些帮助。我的进程需要一个300秒5分钟的计时器来触发事件以刷新网格控件。那很好用。问题是,我需要为用户倒计时5分钟/300秒,以便他们知道下一次刷新将在X秒后发生。目标是倒计时、刷新,并向用户显示下一次刷新 下面的所有代码示例都是我尝试过的示例 我有用于刷新的代码,但是在第一次执行之后发生了一些奇怪的事情。计时器倒计时到0,刷新,然后在300秒时重新启动,再次正常,但每次倒计时后都会闪烁第二个计时器。所以我看到了300299298。。。然后是另外的3

大家好, 我正在努力解决一个编码问题,我需要一些帮助。我的进程需要一个300秒5分钟的计时器来触发事件以刷新网格控件。那很好用。问题是,我需要为用户倒计时5分钟/300秒,以便他们知道下一次刷新将在X秒后发生。目标是倒计时、刷新,并向用户显示下一次刷新

下面的所有代码示例都是我尝试过的示例

我有用于刷新的代码,但是在第一次执行之后发生了一些奇怪的事情。计时器倒计时到0,刷新,然后在300秒时重新启动,再次正常,但每次倒计时后都会闪烁第二个计时器。所以我看到了300299298。。。然后是另外的300299298。。。;因此,它看起来像是3002992983002972996298,等等,看起来很恶心。更不用说看20分钟的电视了

我的300秒计时器是System.Timers.timer int eh,下面是一个示例提醒,它可以工作:

public partial class MasterControl
{
private Timer _t;

public MasterControl()
        {
            InitializeComponent();

        }

public void Dispose()
        {
            _t?.Dispose();
            _handle?.Dispose();
        }

        private void Master_OnLoaded(object sender, RoutedEventArgs e)
        {
            var fd = new FillMaster();
            GridMaster.ItemsSource = fd.GridPopulate("TblName", App.UserName);
            _t = new Timer();
            _t.Elapsed += OnTimedEvent;
            _t.Interval = 300000;
            _t.Enabled = true;
        }
        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                try
                {
                    var fd = new FillMaster();
                    GridMaster.ItemsSource = fd.GridPopulate("TblName", App.UserName);
                }
                catch (SqlException)
                {
                    /*  swallow */
                }
            });
        }
}
我试图做的是添加一个倒计时,填充标签

我补充说

private TimeSpan _time;
private DispatcherTimer _timer;
我将OnTimedEvent代码调整为下面的示例,但它不起作用。这就是它在刷新时开始加倍的地方。我试着看看这是否有效。没有骰子

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Dispatcher.Invoke(() =>
    {
        try
        {
            var fd = new FillMaster();
            GridMaster.ItemsSource = fd.GridPopulate("IntakeCheckList", App.UserName);
            TbCountDown.Content = "";
            _time = TimeSpan.FromSeconds(60);

            _timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
            {
                TbCountDown.Content = _time.ToString("c");
                if (_time == TimeSpan.Zero)
                {
                    _timer.Stop();
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                }

                _time = _time.Add(TimeSpan.FromSeconds(-1));
            }, Application.Current.Dispatcher);

            _timer.Start();
        }
        catch (SqlException)
        {
            /*  swallow */
        }
    });
}
我还发现了一些导致同样问题的代码

private void Countdown(int count, TimeSpan interval, Action<int> ts)
        {
            var dt = new DispatcherTimer {Interval = interval};
            dt.Tick += (_, a) =>
            {
                if (count-- == 0)
                    dt.Stop();
                else
                    ts(count);
            };
            ts(count);
            dt.Start();
        }
如图所示

private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                Countdown(30, TimeSpan.FromSeconds(5), cur => TbCountDown.Content = cur.ToString());

                try
                {
                    var fd = new FillMaster();
                    GridMaster.ItemsSource = fd.GridPopulate("IntakeCheckList", App.UserName);
                }
                catch (SqlException)
                {
                    /*  swallow */
                }
            });
        }
同样的问题也没有解决

private void Countdown(int count, TimeSpan interval, Action<int> ts)
        {
            var dt = new DispatcherTimer {Interval = interval};
            dt.Tick += (_, a) =>
            {
                if (count-- == 0)
                    dt.Stop();
                else
                    ts(count);
            };
            ts(count);
            dt.Start();
        }
最后,是否有办法从System.Timers.Timer或其他您可以帮助我的东西中获取倒计时


谢谢大家!

实际上,您只需要一个简单的Dispatcher和一个DateTime即可循环重置为当前时间+300秒

public partial class MainWindow : Window
{
    private readonly DispatcherTimer timer = new DispatcherTimer();
    private DateTime endTime;

    public MainWindow()
    {
        InitializeComponent();

        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += new EventHandler(OnTimerTick);
        timer.Start();
    }

    private void OnTimerTick(object sender, EventArgs e)
    {
        var now = DateTime.Now;

        if (endTime < now)
        {
            endTime = now.AddSeconds(300);
        }

        label.Content = (endTime - now).ToString(@"mm\:ss");
    }
}

工作完美。我能够将其集成到我的代码中,现在每5分钟或00:00,系统就会重置并开始新的倒计时。谢谢你!