[C#] イベントハンドラを基本から使いこなす!

C#

こんにちは、リバティエンジニア[?]のたくやです。 現役エンジニアとしてアプリケーション開発やWeb制作、SEOやブログ運営をしています。

突然ですが、「イベントハンドラ」ってご存知ですか?

c#で例えば配置したボタンコントロールがクリックされた時に処理したい事がある時は、このボタンのクリックイベントというのに処理を紐づける事で実装する事ができます。

つまり、イベントハンドラは「デリゲート」なんです!
デリゲートについては下の記事を参考にしてみてください。

C# 世界一わかるデリゲート(delegate)について
こんにちは、リバティエンジニアのたくやです。 現役エンジニアとしてアプリケーション開発やWeb制作、SEOやブログ運営をしています。今回はC#における「デリゲート」について学習していきましょう!...

今回はそのイベントハンドラを使いこなすことにより、期待した場所で期待した動作を正しく実装する方法を覚えてもらえればと思います。

では早速見ていきましょう!

C# イベントハンドラとは?

先ほども少しだけ説明しましたが、まずは「イベントハンドラ」とは何か?ということを簡単に説明したいと思います。

イベントハンドラとは、特定のイベントが発生した際に行う”処理”のことです。

イベントハンドラに処理を渡すときは、先程少しだけお話した”デリゲート”を渡してやります。
そうすることで、そのイベントが発生したときに、デリゲートで渡した処理が勝手に走ってくれます。

C# イベントハンドラの仕組み

では次にイベントハンドラの仕組みについてですが、
「なぜ、イベントハンドラにデリゲートを渡すと勝手に処理してくれるのか?」
このような疑問を持つ方が少なからずいると思います。

なぜ、イベントハンドラにデリゲートを渡すと勝手に処理してくれるのか?

それを知るにはまず、イベントハンドラについて少しだけ知る必要があります。
イベントハンドラの定義を見てみましょう。

IT博士
IT博士

普段何気なく使っている標準関数などの定義を見てみると新しい発見などがあって、楽しいですよ♪

// イベントハンドラの定義
delegate void EventHandler(object snder, EventAgrs e);

この定義を見てみるとわかるのですが、イベントハンドラは”デリゲート”なんです。

VisualStudioなんかの統合開発環境でアプリケーションなどの開発をしている方はイベントの記述について詳しく見たことがない方もいるかもしれません。
便利すぎてそれでも開発できてしまうんです。

IT博士
IT博士

「そんなの常識!知ってるに決まっている!」
という方は先ほどのワタシの発言は忘れてください。。

少し話がずれましたが、本題に戻りましょう。
デリゲートは

「同じ戻り値の型で同じ引数の型を持つメソッドを代入できる」

なので、イベントハンドラと同じ型の関数を作って、それを代入すればイベント発生時にその処理を実行してくれるというわけなんです。

イベントハンドラに処理を追加するサンプルコード

文字ばかり読んでもしっくりこないと思うので、一番シンプルな例文をご紹介します!

namespace WindowsFormsApplication
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            // フォームクローズイベントに、Form1_FormClosedメソッドの処理を追加
            FormClosed += new FormClosedEventHandler(Form1_FormClosed);
        }

        /// <summary>
        /// フォームが閉じたら確認のダイアログを表示します。
        /// </summary>
        /// <param name="sender">オブジェクト</param>
        /// <param name="e">イベント</param>
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            MessageBox.Show("フォームのClosedイベント");
        }
    }
}

どうでしょうか。
正直普通にプログラムを組んでいる分には上記のやり方でイベントを追加する。ぐらいの理解で良いと思います。

イベントに登録した関数の引数の

(object sender, FormClosedEventArgs e)

これって何ですか?

 

IT博士
IT博士

やはり気になりますよね!みなさん1度はこの疑問に気が付きますが、意外と理解できていない人が多いんです。

なので、今日覚えてしまってください♪

C#のイベントハンドラなどの引数にある「object sender」とは?

イベントハンドラなどの引数にある「object sender」とはなんだ?と疑問に思う方も多いと思います。
MSDN公式ドキュメントで見てみると、「イベントのソース」や「イベントを発生させるインスタンスを参照します」と記載があります。

…..わからないですよね。

簡単に言うと、「イベントの発生元のコントロールオブジェクト」が格納されています。

例えば、ボタンクリックイベントが発生した場合、発生元のボタンコントロールが入り、
フォームクローズイベントが発生した場合、発生元のフォームコントロールが入ります。


/// <summary>
/// TestButtonのクリックイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
testprivate void TestButton_Click(object sender, EventArgs e)
{
    // ボタンクリック時の処理
    // sender にはこのイベントが発生した元のButtonコントロールが入っています。
}

EventArgs e とは?

こちらもMSDNで見てみると、「イベント データを格納している」や「型 EventArgs から派生し、イベント データを保持します」と記載があります。

IT博士
IT博士

MSDNって公式なので正確な情報源なのですが、言葉が難しいですよね。。

つまり、この「EventArgs e」にはイベントの情報が入っています。

発生したイベントが、EventArgsクラスを継承したクラスのインスタンスが入っています。
これについては今回はそれほど詳しく説明しません。

”イベントクラスのインスタンス”が入っている。と覚えておいて下さい。

まとめ

今回はイベントハンドラについて解説しました。

押さえておいてほしい点としては、

 

・デリゲートは同じ戻り値の型/同じ引数の型を持つメソッドを代入できる
・イベントハンドラとはデリゲートの一種でありイベントが発生した時に行う処理
・引数の一つ目にはイベントの発生元コントロールが入っている
・引数の二つ目には、発生したイベントの情報が入り、その情報というのはEventArgsクラスを継承したクラスのインスタンスである

 

 

ということです。

VisualStudioなんかを使っていると、イベントのコードは自動生成されるので、’なんとなく’でイベント処理を実装していることが多くなってしまいます。

いつかイベントについてトリッキーな実装をする時が来ると思いますので、その時はまたこの記事を参考にしてみてください!

今回のイベント関連で他にも役に立つ記事があるので、良ければ見ていってください。

[C#] Windows.Formsのイベントが発生する順番は?
こんにちは、リバティエンジニアのたくやです。 現役エンジニアとしてアプリケーション開発やWeb制作、SEOやブログ運営をしています。Windowsフォームアプリケーションの開発をしていると、コン...
C# コントロールのイベントを一時的に無効化する方法
イベントを一時的に無効にするこんにちは、リバティエンジニアのたくやです。 現役エンジニアとしてアプリケーション開発やWeb制作、SEOやブログ運営をしています。今回は、何かの処理をしている...
【結論】未経験でプログラミングの独学はぜんぜん可能
完全初心者、未経験でプログラミングの独学はできるのか?という内容についてまとめています。プログラミングの独学は難しいんのではないか。。そんな悩んでる暇があるなら勉強を始めましょう。[結論]プログラミングの独学は可能です。

なにか質問があればお問い合わせフォームでお気軽にお問合せください。
可能な限りすぐにお返事します。
一流プログラマを目指して頑張りましょう!

C#
今日からワタシはプログラマ

コメント