2010-08-13 48 views
8

我已经写了一些代码来处理事件,如下所示:如何知道.net事件是否已处理?

AddHandler myObject.myEvent, AddressOf myFunction 

似乎一切都在第一个工作日,但是当我跑调试器,我发现,通常情况下,myFunction会跑好几次,每次发射了myObject.myEvent。我发现我已经允许代码添加事件处理程序来运行多次,导致这种行为。

有没有办法像这样做?

If myObject.myEvent is not handled Then 
    AddHandler myObject.myEvent, AddressOf myFunction 
End If 

回答

11

假设它不是你的代码发布事件,你不能。这个想法是,用户是相互隔离的 - 你无法找到其他活动用户,自己提高事件等。

如果问题是,你是多次添加自己的处理程序,你应该能够通过跟踪是否已经添加处理程序来解决这个问题。 Steven在添加处理程序之前删除处理程序的想法是一个有趣的解决方法:即使未订阅处理程序,也试图删除处理程序是有效的。但是,我认为这是您应用程序的一种解决方法,并不知道它应该做什么。这是一个非常快速的短期解决方案,但我会担心长期放置它。

+1

“文件,它伤害时,我这样做。“ “所以不要这样做。” – 2010-08-13 13:40:29

+0

你说得对,它是一种黑客行为,特别是因为让你的事件挂钩可以有效地导致内存泄漏。 – 2010-08-13 20:30:34

5

或者:

  1. 不要添加您的处理程序比 一次。

  2. 尝试在添加处理程序之前删除处理程序 。

+0

如果您尝试删除处理程序并且它不存在,它会抛出nullreferenceexception – Sebastien 2014-01-14 22:07:22

+3

虽然它也会引发空引用,但事实并非如此。如果对象不存在,则会引发null错误。在myObject.myEvent上删除处理程序,如果myObject不存在,则会抛出错误。 – user1500403 2015-09-06 00:57:37

0

将您的事件处理程序结果保存到数据库/会话中,然后再次读取它们以检查事件是否已被处理。

2

无法确定处理程序已连接,但在调用AddHandler之前可以安全地调用RemoveHandler。如果还没有处理程序,则RemoveHandler将不起作用。

+1

不正确将发送nullreference异常 – Sebastien 2014-01-14 22:04:35

+0

如果根本没有附加处理程序,则该事件成员将仅为空。但是没有一个好的方法来判断一个特定的处理程序是否已经连接上了。 – Josh 2014-01-17 15:38:35

-3

您可以使用IsHandleCreated属性来检查您的事件是否已经有句柄。

If e.Control.IsHandleCreated = False Then 
      AddHandler e.Control.KeyPress, AddressOf TextBox_keyPress 
    End If 
+0

IsHandleCreated检查窗口句柄,它与查找事件订阅者无关 – 2016-07-12 13:21:22

2

我知道这是一个老的文章,但只是想补充一点对于那些谁过来找在这个方向上的解决方案...

VB.Net创建于<YourEvent>Event的模式的特定的私有成员变量你可以用它来测试Nothing。

Public Event MyClick As EventHandler 

Private Sub OnMyClick() 
    If MyClickEvent IsNot Nothing Then 
     RaiseEvent MyClick(Me, New EventArgs()) 
    Else 
     ' No event handler has been set. 
     MsgBox("There is no event handler. That makes me sad.") 
    End If 
End Sub 

答案从这里来源:Determine if an event has been attached to yet

-1

删除处理程序,然后添加它。这样它就不会被重复。如果您的对象不存在,请小心空引用错误。我也遇到过这种情况,当你在创建处理程序的子程序外移除处理程序时可能会发生这种情况。

if not myObject in nothing then AddHandler myObject.myEvent, AddressOf myFunction 
if not myObject in nothing then AddHandler myObject.myEvent, AddressOf myFunction 
0

我知道我已经晚了几年,但你总是可以在一个类变量的范围内,然后在事后设置它。这并不是一种完全坚定的做事方式,但它比仅仅希望你没有任何东西或每次添加它都更好。在我的情况下,我在一个WinForms应用程序中使用了这个,我想添加一个处理器来拖放到datagridview表面。如果其他datagridview的部分内容尚未完全填充,我想停止此功能。

因此,这将是这样的:

类级别

Private _handlersAdded As Boolean = False 

构造:

Public Sub New() 
    AddHandler dgv.DragEnter, AddressOf DragEnter 
    _handlersAdded = True 
End Sub 

方法确定问题:

Private Sub CheckRowsAreDone() 
    For Each row As DataGridViewRow In dgv.Rows 
    Dim num = 0 

    For i = 0 To row.Cells.Count - 1 
     Dim val = If(Not String.IsNullOrEmpty(row?.Cells(i)?.Value?.ToString), 1, -1) 
     num += val 
    Next 

    If num > -(row.Cells.Count) And num < (row.Cells.Count) Then 
     RemoveHandler dgv.DragEnter, AddressOf DragEnter 
     _handlersAdded = False 
     Exit Sub 
    End If 

    If Not _handlersAdded Then 
     AddHandler dgv.DragEnter, AddressOf DragEnter 
     _handlersAdded = True 
    End If 

    Next 
End Sub 
相关问题