HeyCHのブログ

慢性疲労のへいちゃんです

【C#】簡単なストップウォッチを作ろう Final of The Final

enumでスマートに

Finalと謳ったストップウォッチですが、enumという列挙型を使用することでもっとスマートに書くことができます。
以下に、時刻表示モード、ストップウォッチモード、一時停止モードを想定したenumを記述します。

        enum StopwatchMode
        {
            Time,
            Stopwatch,
            Pause
        }
        StopwatchMode mode = StopwatchMode.Time;

最終的なコード

どうでしょうか、少しだけ可読性がよくなったような気がしないでもありません。
同じ機能を持つストップウォッチでも、このようにかなり違う書き方ができます。

        public Form1()
        {
            InitializeComponent();
        }
        DateTime now;
        DateTime startTime;
        BackgroundWorker bw;
        TimeSpan ts;
        enum StopwatchMode
        {
            Time,
            Stopwatch,
            Pause
        }
        StopwatchMode mode = StopwatchMode.Time;
        private void Form1_Load(object sender, EventArgs e)
        {
            ts = new TimeSpan(0);
            bw = new BackgroundWorker();
            bw.DoWork += Bw_DoWork;
            bw.RunWorkerAsync();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.Text == "Start")
            {
                if (mode != StopwatchMode.Pause)
                {
                    startTime = DateTime.Now;
                }
                else if (mode == StopwatchMode.Pause)
                {
                    startTime = DateTime.Now - ts;
                }
                mode = StopwatchMode.Stopwatch;
                button1.Text = "Pause";
            }
            else
            {
                mode = StopwatchMode.Pause;
                button1.Text = "Start";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            mode = StopwatchMode.Time;
            button1.Text = "Start";
        }
        private void Bw_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                now = DateTime.Now;
                if (mode == StopwatchMode.Stopwatch)
                {
                    ts = now - startTime;
                    try
                    {
                        Invoke((MethodInvoker)delegate ()
                        {
                            label1.Text = String.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
                        });
                    }
                    catch (Exception ex)
                    {
                    }
                }
                else if (mode == StopwatchMode.Time)
                {
                    try
                    {
                        Invoke((MethodInvoker)delegate ()
                        {
                            label1.Text = String.Format("{0:D2}:{1:D2}:{2:D2}", now.Hour, now.Minute, now.Second, now.Millisecond);
                        });
                    }
                    catch (Exception ex)
                    {
                    }
                }
                else if (mode == StopwatchMode.Pause)
                {
                    //何もしない
                }
            }
        }
        List<TimeSpan> tsl = new List<TimeSpan>();
        private void button3_Click(object sender, EventArgs e)
        {
            if (mode!=StopwatchMode.Stopwatch) return;
            tsl.Add(ts);
            TimeSpan tmp = new TimeSpan(0);
            if (tsl.Count <= 1)
            {
                tmp = tsl[tsl.Count - 1];
            }
            else
            {
                tmp = tsl[tsl.Count - 1]- tsl[tsl.Count - 2];
            }
            DataGridViewTextBoxCell jikoku = new DataGridViewTextBoxCell();
            DataGridViewTextBoxCell laptime = new DataGridViewTextBoxCell();
            jikoku.Value = String.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", now.Hour, now.Minute, now.Second, now.Millisecond);
            laptime.Value = String.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", tmp.Hours, tmp.Minutes, tmp.Seconds, tmp.Milliseconds);
            DataGridViewRow r = new DataGridViewRow();
            r.Cells.Add(jikoku);
            r.Cells.Add(laptime);
            dataGridView1.Rows.Add(r);
        }