2017年2月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        

Amazonウィジェット

  • miniPC
  • 最近買った本
  • Raspberry Pi
  • クアッドコプター
  • 書籍ランキング

AdSense

  • 広告
無料ブログはココログ

« C言語 CSVを読み込む関数をsscanfとstrchrで作ってみた。 | トップページ | C++ VisualStudio2013を使ってopenCVのプロジェクトを簡単に試す »

2016年12月 4日 (日)

C# イベントを発生させる続編 イベントを使って値を受け渡しする

C#のフォームアプリケーションを作っていると、描画の更新などイベントを使わなければ回りくどかったり、難しい場合がある。イベントを使いこなせても、今度は値を渡したいとか、どこで発生したイベントかを知らせたり、渡した値でハンドラの振る舞いを変えたいとかいろいろ出てくる。

イベントに値を追加して、イベントハンドラでその値を受け取らせたい場合は、クラスを作ってそれを入れ物として値を受け渡せばよい。じつはそういう例がMouseイベントでも見られる。マウスMoveはEventArgsではなく、マウスの座標をイベントオブジェクトの中に入れ込んだMouseEventArgsという型をやり取りしている。

MouseEventArgsをMSDNを調べてみると、EventArgsというクラスを継承して作られていることがわかる。

https://msdn.microsoft.com/ja-jp/library/system.windows.forms.mouseeventargs(v=vs.110).aspx

つまり、これと同様にしてEventArgsを継承したクラスを用意し、そのクラスに好きな値を持たせればよいことになる。

※マウスイベントの試し方:pictureBoxやパネルの中にあるマウス系イベントのMouseMoveイベントを、フォームデザイナのプロパティで設定してみると、MouseEventHandlerというハンドラが追加されることがわかる。

※手順:pictureBoxをフォームに追加して、プロパティ画面の雷マークを押すと、イベントのプロパティが現れる。この中に、マウスという項目がある。このなかのMouseDownという項目の右をダブルクリックすると、pictureBox1_MouseDownという関数がフォームデザイナでForm内に自動的に追加される。

//色が変化したときにイベントで飛ばすプロパティを入れたクラス
    class ColorEventArgs : EventArgs
    {
        Color c;
        public ColorEventArgs(Color c)
        {
            this.c = c;
        }
        public Color color
        {
            get { return c; }
        }
    }

上記入れ物をイベントに載せて飛ばすためには、
・その型を持ったイベントの宣言
・その型を持ったオブジェクトを受けられるデリゲートの宣言
の2つが必要。

        //イベント
        public event ColorEventHandler CurrentColorChange;

        //ColorEventArgs型のオブジェクトを返すようにする
        public delegate void ColorEventHandler(object sender, ColorEventArgs e);

デリゲートに、イベントが発生したときにやってほしい関数を渡すのを忘れずに。

//イベントで処理する関数を登録
          ceditor.CurrentColorChange += new ColorEditor.ColorEventHandler(this.currentColorChanged);

イベントを発生させるには

        public void setCurrentColor(Color c)
        {
            currentColor = c;
            if (CurrentColorChange != null)
            {
                CurrentColorChange(this, new ColorEventArgs(currentColor));
            }
        }

という風にして、先ほどのイベントを関数のようにして呼ぶ。 そのときに引数として先ほど作ったデータの入れ物型のオブジェクトを作って渡す。

すると、イベントハンドラ先で入れ物を受け取り、そのなかのメンバにアクセスして データを取り出すことができる。この中には、イベントの送り先とかデータを何でも入れられる。 これによりどこが発生させたイベントかを判別することで振る舞いを変えたりできる。

イベントハンドラはこんな風にかける。

        private void currentColorChanged(object sender, ColorEventArgs e)
        {
            colorNum_t num = e.color;
        }

ちなみに、他のイベントハンドラと共用で使いたい場合は、一旦基底クラスのEventArgsで受けておいて、 ほしいクラスのキャストをしてやってもよい。

        private void currentColorChanged(object sender, EventArgs e)
        {
            colorNum_t num = ((ColorEventArgs)e).getColorNum();
        }

イベントを使うとかなり色々なことが出来るようになった気になるが、あまり使いすぎたりあちこちからイベントを発生させたりすると、プログラムの流れが全く読めなくなって困る。

« C言語 CSVを読み込む関数をsscanfとstrchrで作ってみた。 | トップページ | C++ VisualStudio2013を使ってopenCVのプロジェクトを簡単に試す »

C#」カテゴリの記事

コメント


This site has nice content. In addition to that, the content is also interesting to read. The author’s efforts are indeed commendable and I am pleased. I have found this post to contain worthy-reading content. I hope that we will be enlightened on such matters even in the future. Good work!

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/518723/64353159

この記事へのトラックバック一覧です: C# イベントを発生させる続編 イベントを使って値を受け渡しする:

« C言語 CSVを読み込む関数をsscanfとstrchrで作ってみた。 | トップページ | C++ VisualStudio2013を使ってopenCVのプロジェクトを簡単に試す »