如何使用带有TimeSpan和两个复选框的StopWatch来确定计时器是向上计数还是向下计数?

时间:2018-09-30 01:04:06

标签: c# winforms

我希望如果选中checkBox checkBoxCountDown,那么如果计时器已经在运行,则计时器将倒数,然后从该点开始倒数。如果在单击开始按钮之前启动计时器之前已选中该复选框,并且时间为00:00:00:000,请不要倒计时。但是,如果时间是例如01:00:00:000或例如00:00:00:011,则单击开始将倒计时,并且应在到达00:00:00:000时停止

与checkBoxCountUp相同。

其目的是使复选框可以决定是递增还是递减,但我不确定如何使用秒表。

StopWatch只能计数吗?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace StopwatchTimer
{
    public partial class Form1 : Form
    {
        private static readonly Stopwatch watch = new Stopwatch();
        private long diff = 0, previousTicks = 0, ticksDisplayed = 0;

        public Form1()
        {
            InitializeComponent();

            richTextBox1.TabStop = false;
            richTextBox1.ReadOnly = true;
            richTextBox1.BackColor = Color.White;
            richTextBox1.Cursor = Cursors.Arrow;
            richTextBox1.Enter += RichTextBox1_Enter; ;

            UpdateTime();
        }

        private void RichTextBox1_Enter(object sender, EventArgs e)
        {
            btnStart.Focus();
        }

        private void UpdateTime()
        {
            richTextBox1.Text = GetTimeString(watch.Elapsed);
        }

        private string GetTimeString(TimeSpan elapsed)
        {
            string result = string.Empty;

            //calculate difference in ticks
            diff = elapsed.Ticks - previousTicks;

            if (radioButton1.Checked == true)
            { //counting up
                ticksDisplayed += diff;
            }
            else
            { //counting down
                ticksDisplayed -= diff;
            }

            if (ticksDisplayed < 0)
            {
                ticksDisplayed = 0;
            }

            //Make ticksDisplayed to regular time to display in richtextbox
            TimeSpan ctimeSpan = new TimeSpan(ticksDisplayed);

            result = string.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                ctimeSpan.Hours,
                ctimeSpan.Minutes,
                ctimeSpan.Seconds,
                ctimeSpan.Milliseconds);

            previousTicks = elapsed.Ticks;

            return result;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (btnStart.Text == "START")
            {
                diff = 0;
                previousTicks = 0;
                ticksDisplayed = 0;

                watch.Reset();
                watch.Start();
                UpdateTime();
                btnStart.Text = "STOP";
                timer1.Enabled = true;
            }
            else
            {
                watch.Stop();
                btnStart.Text = "START";
                btnPause.Text = "PAUSE";
                timer1.Enabled = false;
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            diff = 0;
            previousTicks = 0;
            ticksDisplayed = 0;

            watch.Reset();
            watch.Start();
            UpdateTime();
        }

        private void trackBarHours_Scroll(object sender, EventArgs e)
        {

        }

        private void trackBarMinutes_Scroll(object sender, EventArgs e)
        {

        }

        private void trackBarSeconds_Scroll(object sender, EventArgs e)
        {

        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            if (btnStart.Text == "STOP")
            {
                if (btnPause.Text == "PAUSE")
                {
                    btnPause.Text = "CONTINUE";
                    watch.Stop();
                    timer1.Enabled = false;
                }
                else
                {
                    btnPause.Text = "PAUSE";
                    watch.Start();
                    timer1.Enabled = true;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            UpdateTime();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

最好使用radiobuttons,但这是您的选择。为了执行您想要的操作,您需要计算两次连续UpdateTime()调用之间的时间差,并从显示的时间开始 add 减去。您还需要跟踪显示的时间,以便每次计时器计时时都可以对其进行更新。

代码:

//I am counting everything in Stopwatch ticks
private long diff = 0, previousTicks = 0, ticksDisplayed = 0;

private string GetTimeString( TimeSpan elapsed ) {
    string result = string.Empty;

    //calculate difference in ticks
    diff = elapsed.Ticks - previousTicks;

    //You can use checkBoxCountUp or checkBoxCountDown instead
    if( radioButton1.Checked == false && radioButton2.Checked == false ) {
        //do nothing
    }
    else if( radioButton1.Checked == true ) { //counting up
        ticksDisplayed += diff;
    }
    else { //counting down
        ticksDisplayed -= diff;
    }

    if( ticksDisplayed < 0) {
        ticksDisplayed = 0;
    }

    //Make ticksDisplayed to regular time to display in richtextbox
    TimeSpan ctimeSpan = new TimeSpan( ticksDisplayed );

    result = string.Format( "{0:00}:{1:00}:{2:00}.{3:000}",
        ctimeSpan.Hours,
        ctimeSpan.Minutes,
        ctimeSpan.Seconds,
        ctimeSpan.Milliseconds );

    previousTicks = elapsed.Ticks;

    return result;
}

别忘了,每次重置diff, previousTicks, ticksDisplayed时都将Stopwatch设置为

编辑

带有跟踪栏的代码:

private void trackBar1_Scroll( object sender, EventArgs e ) { //hour
    //get ticksDisplayed as TimeSpan
    TimeSpan ctimeSpan = new TimeSpan( ticksDisplayed );
    //change only the hour
    TimeSpan htimeSpan = new TimeSpan( ctimeSpan.Days, trackBar1.Value, ctimeSpan.Minutes,
                                       ctimeSpan.Seconds, ctimeSpan.Milliseconds );

    //set it to ticksDisplayed and update.
    ticksDisplayed = htimeSpan.Ticks;


    UpdateTime();
}

private void trackBar2_Scroll( object sender, EventArgs e ) { //min
    TimeSpan ctimeSpan = new TimeSpan( ticksDisplayed );
    TimeSpan mtimeSpan = new TimeSpan( ctimeSpan.Days, ctimeSpan.Hours, trackBar2.Value,
                                       ctimeSpan.Seconds, ctimeSpan.Milliseconds );

    ticksDisplayed = mtimeSpan.Ticks;


    UpdateTime();
}

private void trackBar3_Scroll( object sender, EventArgs e ) { //sec
    TimeSpan ctimeSpan = new TimeSpan( ticksDisplayed );
    TimeSpan stimeSpan = new TimeSpan( ctimeSpan.Days, ctimeSpan.Hours, ctimeSpan.Minutes,
                                       trackBar3.Value, ctimeSpan.Milliseconds );

    ticksDisplayed = stimeSpan.Ticks;


    UpdateTime();
}

现在,每次重置Stopwatch时,都需要这样设置时间:

watch.Reset();
TimeSpan ctimeSpan = new TimeSpan( 0, trackBar1.Value, trackBar2.Value, trackBar3.Value, 0 );
diff = 0;
previousTicks = 0;
ticksDisplayed = ctimeSpan.Ticks;