C#重置倒数计时器,DispatcherTimer-在Windows商店应用(C# Reset a

2019-10-21 11:03发布

我是一个C#newbie_and在general_编程和Ι'm试图建立一个倒数计时器数学测验的应用程序。

我生成公式每个用户点击启动按钮时,我给他一个最大60秒的时间回答。 用户 - 无论是回答他的答案是错还是对不matter_和可他/她可以再次新方程点击。 所以,我希望计时器向用户显示一个新的随机方程每次重置。 到目前为止,我只设法在60秒的时间跨度流逝但即使是不正常复位这一点,有时它会显示59或58秒而不是60。

到目前为止,阅读等问题has't帮了我很多,计时器混淆了我。 我也接受建议,让我的代码更简单,更优雅。

这里是我的代码:

EquationView.xaml.cs

public sealed partial class EquationView : Page
    {
        DispatcherTimer timer = new DispatcherTimer();
        int tick = 60;
        int result;

        public EquationView()
        {
            this.NavigationCacheMode = NavigationCacheMode.Enabled;
            this.InitializeComponent();
        }

        private void startButton_Click(object sender, RoutedEventArgs e)
        {
            // Once clicked then disabled
            startButton.IsEnabled = false;

            // Enable buttons required for answering 
            resultTextBox.IsEnabled = true;
            submitButton.IsEnabled = true;

            var viewModel = App.equation.GenerateEquation();
            this.DataContext = viewModel;
            result = App.equation.GetResult(viewModel);

            timer.Interval = new TimeSpan(0, 0, 0, 1);
            //timer.Tick += new EventHandler(timer_Tick);
            timer.Tick += timer_Tick;
            timer.Start();
            DateTime startTime = DateTime.Now;

            // Reset message label
            if (message.Text.Length > 0)
            {
                message.Text = "";
            }

            // Reset result text box
            if (resultTextBox.Text.Length > 0)
            {
                resultTextBox.Text = "";
            }
        }

        private void timer_Tick(object sender, object e)
        {
            Countdown.Text = tick + " second(s) ";
            if (tick > 0)
                tick--;
            else
            {
                Countdown.Text = "Times Up";
                timer.Stop();
                submitButton.IsEnabled = false;
                resultTextBox.IsEnabled = false;
                startButton.IsEnabled = true;
                tick = 60;
            }

        }

        private void submitButton_Click(object sender, RoutedEventArgs e)
        {
            timer.Stop();
            submitButton.IsEnabled = false;
            resultTextBox.IsEnabled = false;

            if (System.Text.RegularExpressions.Regex.IsMatch(resultTextBox.Text, "[^0-9]"))
            {
                MessageDialog msgDialog = new MessageDialog("Please enter only numbers.");
                msgDialog.ShowAsync();

                resultTextBox.Text.Remove(resultTextBox.Text.Length - 1);

                //Reset buttons to answer again
                submitButton.IsEnabled = true;
                resultTextBox.IsEnabled = true;
                timer.Start();
            }
            else
            {
                try
                {
                    int userinput = Int32.Parse(resultTextBox.Text);

                    if (userinput == result)
                    {
                        message.Text = "Bingo!";
                        App.player.UpdateScore();
                        startButton.IsEnabled = true;
                    }
                    else
                    {
                        message.Text = "Wrong, sorry...";  
                        startButton.IsEnabled = true;
                    }
                }
                catch (Exception ex)
                {
                    MessageDialog msgDialog = new MessageDialog(ex.Message);
                    msgDialog.ShowAsync();
                    submitButton.IsEnabled = true;
                    resultTextBox.IsEnabled = true;
                    timer.Start();
                }


            }
        }

Answer 1:

在我看来,你至少有两个显著的​​问题在这里。 第一个是你的定时器可能会带给用户超过60秒,由于Windows线程调度不准确(即每一跳都会发生在略微超过1秒的时间间隔)。 其他(和更切合你的问题)是你不复位tick值为60,除了当计时器已经过去。

对于后一个问题,倒不如简单地重置倒计时值时, 开始计时,而不是试图记住无处不在您停止它。

为了解决这个问题和第一个问题,摆脱了tick领域完全改变你的代码看起来更象这样:

    static readonly TimeSpan duration = TimeSpan.FromSeconds(60);
    System.Diagnostics.Stopwatch sw;

    private void startButton_Click(object sender, RoutedEventArgs e)
    {
        // Once clicked then disabled
        startButton.IsEnabled = false;

        // Enable buttons required for answering 
        resultTextBox.IsEnabled = true;
        submitButton.IsEnabled = true;

        var viewModel = App.equation.GenerateEquation();
        this.DataContext = viewModel;
        result = App.equation.GetResult(viewModel);

        sw = System.Diagnostics.Stopwatch.StartNew();
        timer.Interval = new TimeSpan(0, 0, 0, 1);
        timer.Tick += timer_Tick;
        timer.Start();

        // Reset message label
        if (message.Text.Length > 0)
        {
            message.Text = "";
        }

        // Reset result text box
        if (resultTextBox.Text.Length > 0)
        {
            resultTextBox.Text = "";
        }
    }

    private void timer_Tick(object sender, object e)
    {
        if (sw.Elapsed < duration)
        {
            Countdown.Text = (int)(duration - sw.Elapsed).TotalSeconds + " second(s) ";
        }
        else
        {
            Countdown.Text = "Times Up";
            timer.Stop();
            submitButton.IsEnabled = false;
            resultTextBox.IsEnabled = false;
            startButton.IsEnabled = true;
        }
    }

通过这种方式,它会不完全无论何时 Tick事件发生时,该代码仍将正确计算实际的剩余时间和使用,用于显示和告知的时间是否已到。



文章来源: C# Reset a countdown timer-DispatcherTimer- in windows store app