Controlのイベントに動的に処理をアタッチする

メモ。

こんなインタフェースがあったとして、

public interface IAction
{
    void Run();
}

このインタフェースのRunメソッドを、任意の名前を持つコントロール(System.Windows.Forms.Control)の、任意の名前を持つイベントに動的にアタッチするメソッドはこんな感じで。

public void AttachEvent(Form form, string controlName, string eventName, IAction action)
{
    Control[] controls = form.Controls.Find(controlName, true);
    if (controls != null && controls.Length > 0)
    {
        foreach (Control control in controls)
        {
            EventInfo eventInfo = control.GetType().GetEvent(eventName);
            if (eventInfo != null)
            {
                eventInfo.AddEventHandler(control, 
                    new EventHandler(
                    delegate(object sender, EventArgs e)
                    {
                        action.Run();
                    })
                    );
            }
        }
    }
}

Clickイベントだとこれで問題無し。しかし、当然ながらイベントの型がEventHandler以外だと例外が発生する。イベントの型はEventInfo::EventTypeで取れるので、この情報を使ってイベントハンドラ自体も生成しないと駄目。