.net WinForms:如何以编程方式触发事件处理程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/372974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:50:54  来源:igfitidea点击:

WinForms: How to programmatically fire an event handler?

.netwinformsevents

提问by Ian Boyd

I want to programmatically invoke an event handler for a control. For example:

我想以编程方式调用控件的事件处理程序。例如:

DateTimePicker dtpLastConsummated;

I want to trigger the TextChanged event handler for the dtpLastConsummated, how can i do it?

我想为 触发 TextChanged 事件处理程序,我该dtpLastConsummated怎么做?

In other languages I would call something akin to:

在其他语言中,我会称之为类似于:

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

but in .NET you can have multiple event handlers:

但在 .NET 中,您可以有多个事件处理程序:

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

so you need a way to trigger all the attached event handlers.

所以你需要一种方法来触发所有附加的事件处理程序。



Answer

回答

The following code will fire the event:

以下代码将触发事件:

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

And here's the code of the static toolkit function:

这是静态工具包函数的代码:

/// <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 });
}


Note:I'm not creating a subclass of every control in the .NET framework, and every 3rd party control, and convincing an enterprise worth of developers to retrofit every form to use my custom controls.

注意:我不会为 .NET 框架中的每个控件和每个 3rd 方控件创建一个子类,并说服具有企业价值的开发人员改造每个表单以使用我的自定义控件。

采纳答案by foson

3 suggestions to fire the TextChanged Event:

触发 TextChanged 事件的 3 条建议:

Manually change the text:

手动更改文本:

        string s = dateTimePicker1.Text;
        dateTimePicker1.Text = String.Empty;
        dateTimePicker1.Text = s;

or

或者

Inherit from DateTimePicker and create a new method that exposes / calls DateTimePicker's protected OnTextChanged

从 DateTimePicker 继承并创建一个公开/调用 DateTimePicker 受保护的 OnTextChanged 的​​新方法

public class MyDateTimePicker : DateTimePicker
{
    public void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
    }
}

or

或者

If you don't like OOP and want to break encapsulation, you can access the protected OnTextChanged method through reflection:

如果你不喜欢 OOP 并且想打破封装,你可以通过反射访问受保护的 OnTextChanged 方法:

        MethodInfo onTextChanged = dateTimePicker1.GetType().GetMethod("OnTextChanged", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        onTextChanged.Invoke(dateTimePicker1, new object[] { new EventArgs() });

回答by Matt Hamilton

Button in Windows Forms is a special case, because it has a PerformClickmethod to do exactly what you're talking about. For other events in other controls, though, there's really nothing similar.

Windows 窗体中的 Button 是一个特例,因为它有一个PerformClick方法来完成你所说的。但是,对于其他控件中的其他事件,确实没有类似之处。

回答by Jon B

You can inherit from that class and create a new method that calls the protected OnSomeEvent() method.

您可以从该类继承并创建一个调用受保护的 OnSomeEvent() 方法的新方法。

class MyButton : Button
{
    public void CauseClick()
    {
        this.OnClick();
    }
}

As Matt pointed out, you can use PerformClick() for this specific example. However, most events don't have corresponding public functions to trigger them.

正如马特指出的那样,您可以在此特定示例中使用 PerformClick()。但是,大多数事件没有相应的公共函数来触发它们。

回答by Anjan Kant

Following code helped me to fire event

以下代码帮助我触发事件

ddlTopic_SelectedIndexChanged(this, new EventArgs());

Actual Event

实际事件

private void ddlTopic_SelectedIndexChanged(object sender, EventArgs e)
{
   // do something
}