概要
複数あるCheckBoxが、それぞれ別のイベントからCheckBoxがONになった時に、どのチェックボックスかを判断してそれぞれ任意の時間後にOFFにする機能を実装したいと思いました。
こういったWinFormsなどのGUI操作は非同期処理が重要だと思うのですが、まだまだ勉強が必要だと理解しています。もっと良い方法等コメント頂けますと幸いです。
実装方法
kusocode.cs
List<CheckBox, DateTime> ChTimeList = new List<CheckBox, DateTime>();
Timer timer = new Timer();
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (((CheckBox)(sender)).Checked)
{
//現在時刻取得
DateTime dt = DateTime.Now;
//入力したリセットまでの時間
int resetTime = int.Parse(txtReset.Text);
//呼びだされたchboxとリセットの時刻を保持
ChTimeList.Add(((CheckBox)(sender)), dt.AddSeconds(resetTime));
//1秒周期でメソッド実行
timer.Tick += new EventHandler(chReset);
timer.Interval = 1000;
timer.Start();
}
}
//chリセット処理
private void chReset(object sender, EventArgs e)
{
List<CheckBox> removeList = new List<CheckBox>();
//Dictionaryの要素がなければ何もしない
if (ChTimeList.Count == 0)
{
return;
}
foreach (KeyValuePair<CheckBox, DateTime> a in ChTimeList)
{
//要素が今の時間より過去ならリセット
if (DateTime.Compare(a.Value, DateTime.Now) < 0)
{
a.Key.Checked = false;
removeList.Add(a.Key);
}
}
//削除リスト
foreach (CheckBox ch in removeList)
{
CHandTIME.Remove(ch);
}
timer.Stop();
}
改善点
「とりあえず動く」レベルなので改善したいところを上げていきます。
- foreachの処理中に要素が削除され、例外が発生する可能性がある為別のListを作って回していますが、冗長だと思うので改善したい。
- TimerクラスではなくTaskをうまく使えばシンプルにかけるかもしれない。
- 任意の時間で動く処理にDateTimeを使うのはあまり良くない気がする。
まとめ
まだまだC#の素晴らしい便利な機能を知ってはいても使えてないので、もっとサンプルなどを見て良いコードが書きたい。WinFormsはサンプルが少ないのでどんどん投稿していきたいと思います。