1. イベントとは
クラスやオブジェクトは、イベントを通じて発生した関連する事柄を他のクラスやオブジェクトに通知することができます。イベントを送信(または発生)するクラスは「パブリッシャー」と呼ばれ、イベントを受信(または処理)するクラスは「サブスクライバー」(サブスクライバー)と呼ばれます。
一般的な C# Windows フォームまたは Web アプリケーションでは、ボタンやリスト ボックスなどのコントロールによって発生するイベントをサブスクライブできます。統合開発環境 (IDE) を使用して、コントロールによって発行されたイベントを参照し、処理するイベントを選択できます。 IDE は、空のイベント ハンドラー メソッドと、イベントをサブスクライブするコードを自動的に追加します。
2. イベント属性の概要
イベントがいつトリガーされるかを決定するのは発行者であり、イベントに対する応答はサブスクライバーが決定します。
イベントには複数の購読者が含まれる場合があります。サブスクライバーは、複数のパブリッシャーからの複数のイベントを処理できます。
サブスクライバーのいないイベントは決して起動しません。
イベントは通常、グラフィカル ユーザー インターフェイスのボタンやメニュー オプションのクリックなどのユーザー アクションを表すために使用されます。
イベントに複数のサブスクライバーがある場合、イベントが発生すると、デフォルトでイベント ハンドラーが同期的に呼び出されます。
イベントは、EventHandler デリゲートと EventArgs 基本クラスに基づいています。
3. イベントのサブスクリプションとキャンセル
イベントが発生したときに呼び出されるカスタム コードを作成したい場合は、他のクラスによって発行されたイベントをサブスクライブできます。たとえば、ボタンのクリック イベントをサブスクライブして、ユーザーがボタンをクリックしたときにアプリケーションに便利なアクションを実行させることができます。
1. IDEを使用してイベントをサブスクライブする
図3-1-1 新しいWinFormプロジェクトを作成する
図3-1-2 図1をダブルクリックすると自動作成されるコード
図 3-1-3 図 2 に加えて、このコード行も InitializeComponent メソッドに自動的に追加されます
2. プログラムでイベントをサブスクライブします
新しい WinForm プログラムであると仮定して、イベントを作成します自分たちで手動で。 InitializeComponent メソッドの下に this.Load += と入力すると、プロンプトが表示されます。このとき、「Tab キー」を押します。
図 3-2-1
イベントハンドラーも自動的に作成されます。その効果は、前のセクションで空白を直接ダブルクリックして作成したコードと同じであると言えます。コードは次のとおりです。
public partial class Form1 : Form { public Form1() { InitializeComponent(); this.Load += Form1_Load; } private void Form1_Load(object sender, EventArgs e) { throw new NotImplementedException(); } }
今回は、を直接使用します。 lambda メソッドを使用してイベントの登録を完了します。空白部分をクリックすると、マウス クリックの座標が表示されます。
public partial class Form1 : Form { public Form1() { InitializeComponent(); //this.Load += Form1_Load; //点击事件(lambda 方式创建) this.Click += (s, e) => { MessageBox.Show($"{((MouseEventArgs)e).Location}"); }; } private void Form1_Load(object sender, EventArgs e) { throw new NotImplementedException(); } }
【注意事項】 この内容には、vs2015 以降でのみサポートされている $: (C# 6) の構文が含まれています。 $"{msg}" は string.Format("{0}", msg) と同等です。msg は変数を参照します。
3. 匿名メソッドを使用してイベントをサブスクライブします
public Form1() { InitializeComponent(); //this.Load += Form1_Load; //点击事件(lambda 方式创建) //this.Click += (s, e) => //{ // MessageBox.Show($"{((MouseEventArgs)e).Location}"); //}; //使用匿名方法创建事件 this.Click += delegate (object sender, EventArgs e) { var mouseEventArgs = (MouseEventArgs)e; var mouseLocation = mouseEventArgs.Location; MessageBox.Show($"X: {mouseLocation.X}, Y: {mouseLocation.Y}"); }; }
【注意】イベントをサブスクライブするために匿名関数を使用すると、イベントのサブスクリプション解除プロセスがさらに面倒になります。この場合にサブスクライブを解除するには、イベントのサブスクリプション コードに戻り、匿名メソッドをデリゲート変数に格納してから、デリゲートをイベントに追加する必要があります。一般に、コード ビハインドでイベントのサブスクライブを解除する必要がある場合は、匿名関数を使用してイベントをサブスクライブしないことをお勧めします。
4. サブスクライブを解除する
イベントの発生時にイベント ハンドラーが呼び出されないようにするには、イベントのサブスクライブを解除します。リソースのリークを防ぐには、サブスクライバ オブジェクトを解放する前にイベントのサブスクライブを解除してください。イベントのサブスクライブを解除する前に、イベントの基礎となる発行オブジェクト内のマルチキャスト デリゲートは、サブスクライバーのイベント ハンドラーをカプセル化するデリゲートを参照します。パブリッシング オブジェクトがその参照を保持している限り、サブスクライバ オブジェクトはガベージ コレクションによって削除されません。イベントのサブスクライブを解除するには、減算代入演算子 (-=) を使用します。
This.Load -= Form1_Load; //減算代入演算子(-=)を使用してイベントを購読解除します
【備考】すべての購読者がイベントを購読解除した後、パブリッシャークラスのイベントインスタンスはヌル。