【.Net5】WinFormで時計2【System.Timers.Timer】

C# コンピュータ
C#
以前に作成した時計はタイマーがSystem.Threading.Timerでしたが、タイマーをSystem.Timers.Timerに変更したバージョンになります。
【.Net5】WinFormで時計
プロジェクトの作成 PowerShellで実行。要dotnet.exe mkdir Clock3 cd Clock3 dotnet new winforms code . ソースコード ファイル名:Form1.cs using System...

プロジェクトの作成

PowerShellで実行。要dotnet.exe

 

mkdir Clock4
cd Clock4
dotnet new winforms
code .

ソースコード

ファイル名:Form1.cs

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

namespace Clock4
{
    public partial class Form1 : Form
    {
        PictureBox picbox1 = new PictureBox
        {
            Dock = DockStyle.Fill,
        };
        Button button1 = new Button
        {
            Dock = DockStyle.Bottom,
            Text = "Start",
            Height = 80,
        };
        Bitmap bmp = null;
        Font fnt = new Font("MS UI Gothic", 48);

        System.Timers.Timer timer;


        public Form1()
        {
            InitializeComponent();

            this.Controls.Add(button1);
            this.Controls.Add(picbox1);

            this.timer = new System.Timers.Timer(50);

            this.timer.Elapsed += (s, e) =>
            {
                try
                {
                    timer.Stop();

                    if (this.bmp == null)
                    {
                        this.bmp = new Bitmap(this.picbox1.Width, this.picbox1.Height);
                    }
                    using(var g = Graphics.FromImage(this.bmp))
                    {
                        DateTime dt = DateTime.Now;
                        string text = dt.ToString("HH:mm:ss");
                        SizeF stringSize = g.MeasureString(text, fnt);
                        int x = (bmp.Width - stringSize.ToSize().Width) / 2;
                        int y = (bmp.Height - stringSize.ToSize().Height) / 2;
                        g.FillRectangle(
                            Brushes.White, x, y, stringSize.ToSize().Width, stringSize.ToSize().Height);
                        g.DrawString(text, fnt, Brushes.Black, x, y);
                    }
                    picbox1.Invoke(new Action(() =>
                    {
                        this.picbox1.Invalidate();
                    }));
                }
                finally
                {
                    timer.Start();
                }
            };

            this.picbox1.Resize += (s, e) =>
            {
                lock(this)
                {
                    if (this.bmp != null)
                    {
                        this.bmp.Dispose();
                        this.bmp = null;
                    }
                }
            };
            this.picbox1.Paint += (s, e) =>
            {
                lock(this)
                {
                    if (this.bmp != null)
                    {
                        e.Graphics.DrawImageUnscaled(this.bmp, 0, 0);
                    }
                }
            };
            
            this.Load += (s, e) =>
            {
                this.button1.Text = "Stop";
                this.timer.Start();                
            };

            this.FormClosed += (s, e) =>
            {
                timer.Stop();
                using(timer){}
            };
            
            this.button1.Click += (s, e) =>
            {
                if (this.button1.Text == "Start")
                {
                    this.button1.Text = "Stop";
                    this.timer.Start();
                }
                else
                {
                    this.button1.Text = "Start";
                    this.timer.Stop();
                }
            };
        }
    }//class
}//ns
タイマーイベント内でタイマーを一度ストップしてからイベント処理を実行し、処理が終了後タイマーを再開させています。
イベント処理が終了する前に次のイベントが発生の防止を狙っています。
あと、picbox1.Invokeでの処理をpicbox1.Invalidate()のみに限定してみました。

見た目は変更なしです。

コメント