ここまでに作成したプログラムの時刻が更新されない理由は、時刻更新のTimerコンポーネント(「secTimer」オブジェクト)と時刻表示のLabelコントロール(「timeNow」オブジェクト)が結び付けられていないからである。この結び付けは「イベント」という機能を利用することで実現できる。
イベントとは、前述したように、フォームやコントロール、コンポーネントなどのオブジェクトが発行するメッセージのことである。このイベントが発生したときに実行するイベント・ハンドラ(=イベント処理)のメソッドを、[プロパティ]ウィンドウのイベント項目で設定することができる。これによって設定されたイベント・ハンドラを通じて、オブジェクト(この例では「secTimer」オブジェクト)とオブジェクト(この例では「timeNow」オブジェクト)を結び付けることが可能となる(イベントやメッセージ、メッセージ・ハンドラについてよく分からなければ、前述の内容を参照してほしい)。
よって、Timerコンポーネント(「secTimer」オブジェクト)は1秒ごとに時間経過のイベントを発行するので、それを処理するイベント・ハンドラのメソッドを追加する必要がある。
次の画面は、実際に、[プロパティ]ウィンドウのイベント項目にイベント・ハンドラとなるメソッドを追加しているところだ。
[プロパティ]ウィンドウのイベント項目の[動作]カテゴリの中にある[Elapsed](=時間経過)という項目部分をダブルクリックすると、Elapsedイベントのイベント・ハンドラとして「secTimer_Elapsed」メソッドが自動的に追加される(追加されるメソッドの命名パターンは「<オブジェクト名>_<イベント名>」という形式になる)。メソッドが追加されると、次の画面のように、コード・エディタによってそのメソッドのソース・コードが表示される。
自動追加されたElapsedイベントのイベント・ハンドラは次のようなものだ。
private void secTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
}
このsecTimer_Elapsedメソッドは、第1パラメータ(object sender)に「イベントの送り主(本稿の例では、TimerコンポーネントであるsecTimerオブジェクト)」が渡され、第2パラメータには「Elapsedイベントのデータ(具体的には、イベントが発生した時刻などを示すSystem.Timers名前空間のElapsedEventArgsクラスのオブジェクト)」が引き渡される(なお、これらのパラメータは使う必要がなければ、使わなくてよい)。
Elapsedイベントにより、このメソッドが1秒ごとに呼び出されることになるので、このメソッドの中に「Labelコントロールのテキストに時刻の文字列を設定する処理」(この処理については後述する)を追加すればよいだろう。これにより、1秒ごとにLabelコントロールの時刻表示が更新されるはずだ(つまり、ここで始めて「secTimer」オブジェクトと「timeNow」オブジェクトが結び付けられる)。
しかし、よく考えると、「時計」アプリケーションを起動して1秒が経過するまでは、時刻表示が更新されずに、先ほどのLabelコントロール(「timeNow」オブジェクト)のTextプロパティで設定した「12時34分 56秒」が表示されてしまうことになる。そこで、Windowsフォーム(「Display」クラス)が起動したときにも、同じように時刻表示の更新を行いたい。
そこで次に、Windowsフォームの起動時に時刻表示を更新する処理も追加してみよう。
Windowsフォームの起動時に時刻表示を更新するには、WindowsフォームのLoad(=起動)イベントのイベント・ハンドラに、TimerコンポーネントのElapsedイベントと同じ「時刻の文字列を設定する処理」を追加すればよい。
WindowsフォームのLoadイベントのイベント・ハンドラも、[プロパティ]ウィンドウのイベント項目の[動作]カテゴリの中にある[Load]という項目をダブルクリックすると、Loadイベント・ハンドラとして「Display_Load」メソッドを自動的に追加できる(追加されるメソッドの命名パターンは「<クラス名>_<イベント名>」の形式)。
しかし、Loadイベントのイベント・ハンドラは、もっと手軽に追加することができる。実は、次の画面のように、Windowsフォームをダブルクリックするだけで自動的に追加することができるのだ。なお本稿の例では、Labelコントロールがフォーム全体を覆いつくしているので、タイトル部分をダブルクリックする必要がある(間違って、Labelコントロールをダブルクリックしないように注意すること)。
メソッドが追加されると、次の画面のように、コード・エディタによってそのメソッドのソース・コードが表示される。
自動追加されたLoadイベントのイベント・ハンドラは次のようなものだ。
private void Display_Load(object sender, System.EventArgs e)
{
}
このDisplay_Loadメソッドは、第1パラメータ(object sender)には「イベントの送り主(本稿の例では、WindowsフォームであるDisplayオブジェクト)」が渡され、第2パラメータには「Loadイベントのデータ(具体的には、System名前空間EventArgsクラスのオブジェクト。実質的なイベント・データは何もない)」が引き渡される。
Loadイベントにより、このメソッドが起動時に呼び出されることになるので、このメソッドの中に「Labelコントロールのテキストに時刻の文字列を設定する処理」(この処理については後述する)を追加すればよい。これにより、起動時にもLabelコントロールの時刻表示が更新されるはずだ。
以上で設計したとおりの1秒ごとに時刻表示を更新する「時計」アプリケーションが実現できるだろう。
しかしここでさらに考えてみると、LoadイベントとElapsedイベントのイベント・ハンドラには、「Labelコントロールのテキストに時刻の文字列を設定する処理」というまったく同じ処理が存在する。よって、この2つの処理を1つのメソッドにまとめることができるはずだ。次に、複数の処理を1つのメソッドにまとめる方法を解説する。
Copyright© Digital Advantage Corp. All Rights Reserved.