イベント ハンドラーを動的に割り当てる: 可能ですか?
ソフトウェア開発において、イベント ハンドラーは UI 要素間のイベント駆動型の対話を確立するために重要です。そして基礎となるコード。ただし、よくある疑問が生じます: あるコントロールに割り当てられたイベント ハンドラーを「盗んで」別のコントロールに割り当てることは可能ですか?
コンパイラの制限
割り当て時のイベント ハンドラーで = 演算子を使用すると、コンパイラーは、すでに割り当てられているイベント ハンドラーの割り当てを制限します。 btn1 に割り当てられたイベント ハンドラーを btn2 で再利用しようとすると、コンパイラ エラーが発生します。
リフレクション: 解決策
コンパイラの制限にもかかわらず、それは実際に可能です。リフレクションを使用して実行時にイベント ハンドラーを転送します。このアプローチでは、コントロール クラスのプライベート メンバーと内部メンバーに直接アクセスする必要があります。
コード サンプル
次のコード スニペットを考えてみましょう。
using System; using System.ComponentModel; using System.Windows.Forms; using System.Reflection; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); button1.Click += new EventHandler(button1_Click); // Get secret click event key FieldInfo eventClick = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static); object secret = eventClick.GetValue(null); // Retrieve the click event PropertyInfo eventsProp = typeof(Component).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); EventHandlerList events = (EventHandlerList)eventsProp.GetValue(button1, null); Delegate click = events[secret]; // Remove it from button1, add it to button2 events.RemoveHandler(secret, click); events = (EventHandlerList)eventsProp.GetValue(button2, null); events.AddHandler(secret, click); } void button1_Click(object sender, EventArgs e) { MessageBox.Show("Yada"); } } }
このコードでは、秘密の内部イベント キーが取得され、btn1 のイベント ハンドラー リストにアクセスするために使用されます。その後、イベント ハンドラーは btn1 から削除され、btn2 に追加されます。
複雑さと制限
リフレクションはイベント ハンドラーを転送する方法を提供しますが、次の点に注意することが重要です。このアプローチは複雑なので、慎重に使用する必要があります。これには、コントロール クラスの内部実装の詳細へのアクセスが含まれます。これは、フレームワークのバージョンが異なると変更される可能性があります。
以上がC# でイベント ハンドラーを動的に再割り当てできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。