c# – 在其他事件处理程序前添加自己的事件处理程序

当我在VB中使用AddHandler将我自己的方法添加到Click事件时:

  AddHandler Button.Click, AddressOf myButton_Click

我看到我的代码最后执行 – 在Button_Click事件的其他事件处理程序之后.
有没有办法在其他事件之前插入我的事件处理程序,以便它首先执行?

我将此问题标记为C#以及VB,如果您有任何建议,请随意使用任何一种语言.
谢谢!

最佳答案
单个事件的处理程序的执行顺序不能通过内置事件本身的基本行为来控制. MulticastDelegates是处理程序的“包”,他们只是一次抓取一个.请记住,这是大多数开发人员期望这样做的方式,允许依赖于订单的事件处理程序可能会很危险.事件处理程序通常不应该彼此了解,因为如果它们依赖于在另一个处理程序之前或之后执行,它们首先必须知道另一个处理程序的存在(违反信息隐藏和其他几个设计原则),其次,如果该订单发生变化,行为将被破坏.

如果你理解了这一切,并且仍然希望控制事件处理程序的执行顺序,那么下面的内容将会让你关闭.

>创建名为MyHandlers的事件处理程序类型的有序委托集合.这将是实际事件的MulticastDelegate实现的代理.
>创建一个实际附加到内置事件的“主”处理程序方法,并迭代MyHandlers并调用每个方法.
>定义一些从列表中添加和删除处理程序的方法.其中一些可以使用自定义事件“属性”来完成,但这将仅定义添加和删除行为,而不是插入.

代码可能如下所示:

private List<EventHandler> MyHandlers = new List<EventHandler>();

private void MasterClickHandler(object sender, EventArgs e)
{
   foreach(var handler in MyHandlers)
      handler(sender, e); 
}

public event EventHandler MyControlButtonClick
{
   add { MyHandlers.Add(value); }
   remove { MyHandlers.Remove(value); }
}

public void InsertButtonClickHandler(EventHandler handler)
{
   MyHandlers.Insert(handler,0); //calling this to add a handler puts the handler up front
}

...

myForm.MyControl.Click += MasterClickHandler;

请注意,您不再将MasterClickHandler以外的处理程序附加到实际事件中;你不能拥有自己的蛋糕,也不能吃它,无论是重写还是保持基本的事件行为.事件“属性”中也没有内置“插入”行为;你必须定义一个允许这个的方法.最后,你永远不应该直接引发事件MyControlButtonClick(尽管你的控件是唯一可以控制的,可以通过代码检查来强制执行).

现在,当您单击按钮时,按钮的内置Click事件将触发MasterEventHandler,它将按照它们附加到MyControlButtonClick的相同顺序执行MyHandlers中的委托(首先执行插入的任何委托,按插入的相反顺序执行) ).如果您将此代码放在带有Button的自定义用户控件中,您甚至可以在控件Click上命名自定义事件,并且控件的外观和工作方式与它包含的Button非常相似,不同之处在于它可以对插入进行额外的控制处理程序.整个事情的美妙之处在于,这个代码没有任何东西可以迫使消费者使用它作为一个普通的“香草”事件.

转载注明原文:c# – 在其他事件处理程序前添加自己的事件处理程序 - 代码日志