从 30 秒倒计时到 0 秒,最后一秒显示 2 位小数 Xamarin.Forms c#

Countdown from 30 seconds to 0 seconds, showing 2 decimals in the last second with Xamarin.Forms c#

我对 Xamarin 很陌生。我想做的是一个计时表。它需要从 30 秒倒数到 0 秒,最后一秒需要显示 2 位小数。当我单击 BtnPause 时,我还需要它暂停,如果我单击 BtnStart,我希望它在我暂停它的那一刻重新启动,所以倒计时必须暂停并在计时器暂停时开始,而不是重置。

这是我的代码,请原谅我的错误和糟糕的编程技巧。

  public partial class MainPage : ContentPage
    {
        private static System.Timers.Timer _timer;
        private double _shotClock = 30;

        public MainPage()
        {
            InitializeComponent();
            _timer = new Timer();

        }

        private void BtnStart_Clicked(object sender, EventArgs e)
        {
            RunTimer();

        }
        private void BtnPause_Clicked(object sender, EventArgs e)
        {
            PauseTimer();
        }

        private void RunTimer()
        {
            if (_shotClock < 1.00)
            {
                _timer.Interval = 10;
            }
            else 
            {
                _timer.Interval = 1000;
            }

            _timer.Start();
            _timer.Elapsed += OnTimedEvent;          

        }

        private void PauseTimer()
        {
            _timer.Stop();
        }

        private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
        {
            Device.BeginInvokeOnMainThread(() => {

                if (_shotClock > 1.00)
                {

                    _shotClock -= 1.00;
                    _shotClock = Math.Round(_shotClock, 2);
                    lblTimer.Text = _shotClock.ToString();
                } 
                else if (_shotClock <= 1.00 && _shotClock > 0.00)
                {
                    _shotClock -= 0.01;
                    _timer.Interval = 10;
                    _shotClock = Math.Round(_shotClock, 2);
                    lblTimer.Text = _shotClock.ToString();
                }
                else
                {
                    lblTimer.Text = "0";
                    _timer.Stop();
                }
            });          
        }
    }

出了什么问题:

我不相信它会计算精确的秒数,尤其是当我调用 Runtimer() 时,前几秒已关闭,我不确定倒计时是一秒。当我调用 Pausetimer() 然后调用 Runtimer() 时,会跳过一秒钟。

有没有更好的编码方式?

还没有编译这个,所以我不确定如果不做一些调整它是否能工作,但我希望你明白了。基本上,您必须手动计算经过的时间。在你的情况下关闭秒数可能是因为使用 Round() 而不是 Floor()

public partial class MainPage : ContentPage
{
    private static System.Timers.Timer _timer;
    private double _shotClock = 30;
    private DateTime _startTime;

    public MainPage()
    {
        InitializeComponent();
        _timer = new Timer();
        _timer.Interval = 10;
        _timer.Elapsed += OnTimedEvent;  
    }

    private void BtnStart_Clicked(object sender, EventArgs e)
    {
        _startTime = DateTime.UtcNow;
        _timer.Start();
    }
    private void BtnPause_Clicked(object sender, EventArgs e)
    {
        _shotClock -= (DateTime.UtcNow - _startTime).TotalSeconds;
        _shotClock = Math.Floor(_shotClock);
        _timer.Stop();
    }        

    private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
    {
        Device.BeginInvokeOnMainThread(() => {
            var elapsedSinceBtnStartPressed = (DateTime.UtcNow - _startTime).TotalSeconds;
            var remaining = _shotClock - elapsedSinceBtnStartPressed;

            if (remaining > 1.00)
            {
                lblTimer.Text = Math.Floor(remaining).ToString();
            } 
            else if (remaining <= 1.00 && remaining > 0.00)
            {
                lblTimer.Text = Math.Round(remaining, 2).ToString();
            }
            else
            {
                lblTimer.Text = "0";
                _timer.Stop();
            }
        });          
    }
}

如果您希望 12.53 显示为 13 而不是 12,您可能还想尝试 Math.Ceiling() 而不是 Math.Floor()。

在已接受答案的帮助下,我掌握了基础知识:

public partial class MainPage : ContentPage
    {
        private static System.Timers.Timer _timer;
        private double _shotClock;
        private DateTime _startTime;



        public MainPage()
        {
            InitializeComponent();
            _timer = new Timer();
            _timer.Interval = 10;
            _timer.Elapsed += OnTimedEvent;
            _shotClock = 30.00;
        }

        private void BtnStart_Clicked(object sender, EventArgs e)
        {
            _startTime = DateTime.UtcNow;     
            _timer.Start();
        }

        private void BtnPause_Clicked(object sender, EventArgs e)
        {


            _timer.Stop();
            var elapsedSinceBtnPausePressed = (DateTime.UtcNow - _startTime).TotalSeconds;
            _shotClock -= elapsedSinceBtnPausePressed;


        }

        private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
        {
            var elapsedSinceBtnStartPressed = (DateTime.UtcNow - _startTime).TotalSeconds;
            var remaining = _shotClock - elapsedSinceBtnStartPressed;

            Device.BeginInvokeOnMainThread(() => {


                if (remaining > 1.00)
                {
                    lblTimer.Text = Math.Floor(remaining).ToString();
                }
                else if (remaining <= 1.00 && remaining > 0.00)
                {
                    lblTimer.Text = Math.Round(remaining, 2).ToString();
                }
                else
                {
                    lblTimer.Text = "0";
                    _timer.Stop();
                }
            });
        }
    }