C#ならボタンがクリックされたとかキーが押されたなどのイベントが発生したらどんな処理をするのかという感じでプログラミングしていきます。イベントは既存のものだけでなく自分で定義することもできます。

例としてメインのフォームとは別にもうひとつフォームを生成します。そしてふたつめのフォームでマウスボタンが押下されたらそれをメインのフォームに伝えて、クリックした旨を表示させます。

それだけなら自分でイベントを実装する必要はありません。これで充分なはずです。

Form1のボタンをクリックしたらForm2が出現します。そしてForm2のクライアント領域をクリックするとクリックされた座標がコンソールに表示されます。

イベントを自分で定義する

ただ、ここでは自分でイベントを実装したいので、あえて面倒な方法をとります。いわばサンプルプログラムです。

Form2クラス側でクライアント領域がクリックされたことを、自分で実装したイベントでForm1クラスに伝えるだけならこれで充分です。

ただこれではForm2のどこがクリックされたのかを伝えることができません。ただクリックされたことを伝えることができるだけです。

イベントハンドラで値を取得できるようにする

そこでクリックされた座標もイベントハンドラで取得できるようにします。

まずEventArgsを継承してMyEventArgsクラスを定義します。コンストラクタに座標を渡せばどこがクリックされたのかをForm1クラスに伝えることができます。

MyEvent2?.Invokeの第二引数にEventArgsのインスタンスではなくMyEventArgsのインスタンスを渡しているのでイベントハンドラでMyEventArgsにキャストしなければクリックされた座標を取得することができません。

デリゲートを宣言してイベントハンドラで自由にデータを取得できるようにする

イベントを送信するときMyEvent?.Invoke(object sender, EventArgs e);のような形にするのが一般的ですが、第二引数はEventArgs型でなければならないのかというとそうではありません。好きな型を渡すことができます。ただし、この場合はイベントを定義するときに以下のような処理をいれる必要があります。

イベントハンドラの引数は自由に設定できる

さらに言ってしまうとMyEvent?.Invoke(object sender, EventArgsまたはそれを継承したクラス e);というような引数の型に縛りがあるわけでもありません。こんなイベントを実装することもできます。

MyEvent?.Invoke();の引数ですが、2個でなければならないという縛りもありません。こんなのもありです。

下記のコードならクリックされた座標だけでなくクリックされた時刻や回数も取得できます。