.net - tiempo - que es un evento de un control
WinForms: ¿Cómo ejecutar mediante programación un controlador de eventos? (4)
El botón en Windows Forms es un caso especial, porque tiene un método PerformClick para hacer exactamente lo que estás hablando. Para otros eventos en otros controles, sin embargo, realmente no hay nada similar.
Deseo invocar programáticamente un controlador de eventos para un control. Por ejemplo:
DateTimePicker dtpLastConsummated;
Quiero activar el controlador de eventos TextChanged para el dtpLastConsummated
, ¿cómo puedo hacerlo?
En otros idiomas llamaría algo similar a:
dtpLastConsummated.TextChanged(this, new EventArgs());
pero en .NET puedes tener múltiples manejadores 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);
por lo que necesita una forma de activar todos los controladores de eventos adjuntos.
Responder
El siguiente código activará el evento:
Toolkit.FireEvent(dtpLastConsummated, "TextChanged", new EventArgs());
Y aquí está el código de la función del kit de herramientas estático:
/// <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: No estoy creando una subclase de todos los controles en el marco .NET, y el control de terceros, y convencer a una empresa de que los desarrolladores adapten todos los formularios para usar mis controles personalizados.
3 sugerencias para activar el evento TextChanged:
Cambia manualmente el texto:
string s = dateTimePicker1.Text;
dateTimePicker1.Text = String.Empty;
dateTimePicker1.Text = s;
o
Heredar de DateTimePicker y crear un nuevo método que exhiba / llame a OnTextChanged protegido por DateTimePicker
public class MyDateTimePicker : DateTimePicker
{
public void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
}
}
o
Si no le gusta el OOP y desea romper la encapsulación, puede acceder al método protegido OnTextChanged a través de la reflexión:
MethodInfo onTextChanged = dateTimePicker1.GetType().GetMethod("OnTextChanged", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
onTextChanged.Invoke(dateTimePicker1, new object[] { new EventArgs() });
Puede heredar de esa clase y crear un nuevo método que llame al método OnSomeEvent () protegido.
class MyButton : Button
{
public void CauseClick()
{
this.OnClick();
}
}
Como señaló Matt, puede usar PerformClick () para este ejemplo específico. Sin embargo, la mayoría de los eventos no tienen funciones públicas correspondientes para activarlos.
El siguiente código me ayudó a despedir el evento
ddlTopic_SelectedIndexChanged(this, new EventArgs());
Evento real
private void ddlTopic_SelectedIndexChanged(object sender, EventArgs e)
{
// do something
}