イベント ハンドラーはコントロール間で転送できますか?
あるコントロールからイベント ハンドラーを「盗んで」別のコントロールに割り当てる機能は、プログラミングコミュニティでは長年にわたって議論のテーマでした。質問で提案されている構文は無効ですが、実行時にコントロール間でイベント ハンドラーを転送することは技術的には確かに可能です。
リフレクション ルート
プライベートおよびWindows フォーム フレームワーク内の特定のメンバーの内部的な性質のため、この偉業を達成するにはリフレクションが必要です。リフレクションを利用すると、通常はアクセスできないプライベート フィールドやプロパティにアクセスできます。
提供されたコード例では、一連のリフレクション操作が実行されます。
これにより、イベント ハンドラーが button1 から button2 に効果的に転送されます。
実装例
これは、で提供されているコードの改訂版です。質問:
using System; using System.ComponentModel; using System.Windows.Forms; using System.Reflection; namespace EventHandlerTransfer { public partial class Form1 : Form { public Form1() { InitializeComponent(); button1.Click += new EventHandler(button1_Click); TransferEventHandler(button1, button2); } private void TransferEventHandler(Control source, Control destination) { // 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 eventsSource = (EventHandlerList)eventsProp.GetValue(source, null); EventHandlerList eventsDestination = (EventHandlerList)eventsProp.GetValue(destination, null); Delegate click = eventsSource[secret]; // Remove it from source, add it to destination eventsSource.RemoveHandler(secret, click); eventsDestination.AddHandler(secret, click); } void button1_Click(object sender, EventArgs e) { MessageBox.Show("Yada"); } } }
結論
この方法でイベント ハンドラーを転送できる機能は強力な機能のように思えるかもしれませんが、使用には注意が必要です。この手法はリフレクションに大きく依存しているため、パフォーマンスに影響を与える可能性があり、潜在的なバグも発生する可能性があります。さらに、Windows フォーム フレームワークのプライベート メンバーを変更することは、フレームワークの将来のバージョンで変更があった場合にアプリケーションが破損する可能性があるため、お勧めできません。
以上がWindows フォームのコントロール間でイベント ハンドラーをプログラムで転送できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。