シンプルなWindowsデスクトップアプリを作ってみました。
「やさしいC#」に載っていたサンプルを元に新たに機能を付け加えてみました。
学習3日目でここまでできるなんて、この本選んで良かったです。
C# 学習3日目 シンプルなWindowsプログラム作ってみた
実は、体調の悪いときにこの本をコーディングせずに読み進めました。
学習2日目の背景にバス(書籍では自動車)の画像と文字を載せるだけの
プログラムを作ったのですが、何となくこのプログラムの演習を進み続けたら、
バスの画像を動かせるのではないかと思って読み進めたのですが、
「タイマーを使えばアニメーションできます」という事みたいです。
タイマーを使う一例として、現在時刻を表示するプログラムがありました。
これだけでデスクトップアプリ成立するんじゃないかと思って、
バスの画像を動かすのをよそに、
さらに、オリジナルを付け加えた形で、
「今日のタイムリミット時計」を作ってみました。
現在時刻とともに、今日の残り時間を表示するだけのプログラムです。
using System;
using System.Windows.Forms;
using System.Drawing;
class TodayClock: Form
{
private Label lb_time;//現在時刻
private Label lb_time_label;//「現在時刻」文字表示
private Label lb_limit_time;//残り時間
private Label lb_limit_label;//「残り時間」文字表示
public static void Main()
{
Application.Run(new TodayClock());
}
public TodayClock()
{
//ウィンドウ
this.Text = "今日のタイムリミット時計";
this.Width= 400;
this.Height= 100;
this.BackgroundImage = Image.FromFile("c:\\images\\bg_blue.png");
//タイマー
Timer tm = new Timer();
tm.Interval= 1000;
tm.Start();
//「現在時刻」というラベル文字のラベル
lb_time_label = new Label();
lb_time_label.Left = 0;
lb_time_label.Font = new Font("Helvatica", 16, FontStyle.Regular);
lb_time_label.BackColor = Color.Transparent;
lb_time_label.ForeColor = Color.Orange;
lb_time_label.Text = "現在時刻:";
lb_time_label.AutoSize = true;
//「残り時間」というラベル文字のラベル
lb_limit_label = new Label();
lb_limit_label.Top = 30;
lb_limit_label.Left = 0;
lb_limit_label.Font = new Font("Helvatica", 16, FontStyle.Regular);
lb_limit_label.BackColor = Color.Transparent;
lb_limit_label.ForeColor = Color.Orange;
lb_limit_label.Text = "残り時間:";
lb_limit_label.AutoSize = true;
//現在時刻の表示
lb_time = new Label();
lb_time.Left = 110;
lb_time.Font = new Font("Helvatica", 16, FontStyle.Bold);
lb_time.BackColor = Color.Transparent;
lb_time.ForeColor = Color.Orange;
lb_time.AutoSize= true;
//残り時間の表示
lb_limit_time = new Label();
lb_limit_time.Top = 30;
lb_limit_time.Left = 110;
lb_limit_time.Font = new Font("Helvatica", 16, FontStyle.Bold);
lb_limit_time.BackColor = Color.Transparent;
lb_limit_time.ForeColor = Color.Orange;
//各ラベルをどの親オブジェクトの上に載せるかを設定
lb_time.Parent= this;
lb_time_label.Parent = this;
lb_limit_time.Parent = this;
lb_limit_label.Parent = this;
//イベントハンドラを登録
tm.Tick += new EventHandler(tm_tick);
}
public void tm_tick(object sender, EventArgs e)
{
//現在時刻を代入
DateTime dt = DateTime.Now;
lb_time.Text = dt.ToLongTimeString();
//追加部分 今日の残り時間 (たったこれだけですが苦労しました)
//残り時間
DateTime dt1 = new DateTime(2023, 1, 1, dt.Hour, dt.Minute, dt.Second);
DateTime dt2 = new DateTime(2023, 1, 2, 0, 0, 0);
TimeSpan dt_diff = dt2.Subtract(dt1);
//残り時間を代入
lb_limit_time.Text = dt_diff.ToString();
}
}
タイマーは、タイマーオブジェクトを作成し、
Intervalプロパティに間隔をミリ秒で指定し、
Start()でタイマーを開始します。
実は、早く何か作りたくて、イベントハンドラの項目の学習をすっ飛ばしました。
ですので、イベントハンドラの部分は今回ここでは記事にしません。
(追記:C#のイベント処理の理解にはデリゲートがわかっていたほうが良さそう)
改めて、学習した際に書きたいと思います。//
「残り時間」は本日24時(翌日0時)まで、何時間あるか?というのを出しています。
その算出する記述の仕方をネットで調べたのですが、なかなかわからず、苦労しました。
残り時間を算出するにはTimeSpan型というのを使うのですが、TimeSpanの計算例をやっても
上手く動きませんでした。
あるサイトのQ&A記事で、
「DateTime型の計算結果がTimeSpan型になるのですか?」
「そうです」
という趣旨のやり取りが載っていて、「そんなことがあるのか」と試してみたら、
実はそれが正解でした。
実行結果
今回、学習を飛び越えすぎたので、次回は元に戻りたいと思います。
(追記) 現在の日付を元に日付計算する形に修正
元のプログラムは、作り物の1月1日に時刻を設定して、1月2日00:00:00との差から
今日の残り時間出していましたが、
できれば、今の日付時刻と、明日の00:00:00の差から、出したいと思い
後日、この検証記事を書きました。
時間計算 ~DateTime型とTimeSpan型の理解~
この記事に従って、tm_tick()の中身を修正してみました。
以下、修正したtm_tick()の部分の抜粋です。
修正後のソースコード (2023-01-13)
public void tm_tick(object sender, EventArgs e)
{
// 修正版
DateTime dt = DateTime.Now;
lb_time.Text = dt.ToLongTimeString();
DateTime todayDate = new DateTime(dt.Year, dt.Month, dt.Day);
DateTime tomorrowDate = todayDate.AddDays(1);//明日の零時
TimeSpan dt_span = tomorrowDate.Subtract(dt);//明日の零時 - 今の時刻
lb_limit_time.Text = dt_span.ToString();//今日の残り時間反映
}
修正後の結果
見た目動作は同じですが、中身が修正済みです。