WinForms: como disparar programaticamente um manipulador de eventos?

Desejo invocar programaticamente um manipulador de eventos para um controle. Por exemplo:

DateTimePicker dtpLastConsummated;

Quero acionar o manipulador de eventos TextChanged para odtpLastConsummated, como eu posso fazer isso?

Em outras línguas, eu chamaria algo semelhante a:

dtpLastConsummated.TextChanged(this, new EventArgs());

mas no .NET você pode ter vários manipuladores de eventos:

dtpLastConsummated.Click +=new EventHandler(dtpLastConsummated_TextChanged);
dtpLastConsummated.Click +=new EventHandler(dtpLastConsummated_AnotherHandler);
dtpLastConsummated.Click +=new EventHandler(dtpLastConsummated_MoreHandlers);
...
dtpLastConsummated.Click +=new EventHandler(dtpLastConsummated_Nminus1);

então você precisa de uma maneira de acionar todos os manipuladores de eventos anexados.

Responda

O código a seguir acionará o evento:

Toolkit.FireEvent(dtpLastConsummated, "TextChanged", new EventArgs());

E aqui está o código da função estática do kit de ferramentas:

/// <summary>
/// Programatically fire an event handler of an object
/// </summary>
/// <param name="targetObject"></param>
/// <param name="eventName"></param>
/// <param name="e"></param>
public static void FireEvent(Object targetObject, string eventName, EventArgs e)
{
   /*
    * By convention event handlers are internally called by a protected
    * method called OnEventName
    * e.g.
    *     public event TextChanged
    * is triggered by
    *     protected void OnTextChanged
    * 
    * If the object didn't create an OnXxxx protected method,
    * then you're screwed. But your alternative was over override
    * the method and call it - so you'd be screwed the other way too.
    */

   //Event thrower method name //e.g. OnTextChanged
   String methodName = "On" + eventName;

   MethodInfo mi = targetObject.GetType().GetMethod(
         methodName, 
         BindingFlags.Instance | BindingFlags.NonPublic);

   if (mi == null)
      throw new ArgumentException("Cannot find event thrower named "+methodName);

   mi.Invoke(targetObject, new object[] { e });
}

Nota: Não estou criando uma subclasse de todos os controles na estrutura .NET, nem todos os controles de terceiros, e convencendo uma empresa de desenvolvedores a modernizar todos os formulários para usar meus controles personalizados.

questionAnswers(4)

yourAnswerToTheQuestion