English 中文(简体)
VB.NET - 通过活动作为参数
原标题:VB.NET - Passing an event as a parameter

我需要将事件作为参数传递给一项功能。 是否有办法这样做?

The reason is that I have a sequence of two lines of code that is littered all over my program, where I dynamically remove the handler to an event, and then set the handler again. I m doing this for several different events and event handlers, so I ve decided to write a function that does this.

举例来说,我要说,我有一部名为“ com”的法典,我有手叫指数ChangedHandler。 在我的法典的几个地方,我有以下两条:

RemoveHandler combobox1.SelectedIndexChanged, AddressOf indexChangedHandler
AddHandler combobox1.SelectedIndexChanged, AddressOf indexChangedHandler

现在,我不想在我的方案上重复上述两条法典(或类似),这样我就想设法这样做:

Private Sub setHandler(evt As Event, hndler As eventhandler)
     RemoveHandler evt, hndler
     AddHandler evt, hndler
End Sub

因此,在我方案出现这两条法典(或类似)的地方,我只能用:

setHandler(combobox1.SelectedIndexChanged, AddressOf indexChangedHandler)

至今为止,“作为事件”的机组职能部分的争论有误。

P.S:我曾在其他几个论坛问过这个问题,并不断问,为什么我想在撤走之后立即放手。 其原因是,在事件发生时,积极增加一门活动手,导致手臂被处决。 为了避免这种情况,即,为了确保在事件发生后立即执行手稿,我每次想积极补充手稿时,先撤除手稿。

You might be asking why the handler would be added several times in the first place... The reason is because I add the handler only after a particular event, say E1, in my form has occurred (I add the handler within the handler of event E1). And event E1 can occur several times within my form. If I do not remove the handler each time before adding it again, the handler gets added and thus executed several times.

不管怎样,这一职能范围内进行的处理对我来说,目前并不具有最终重要性,而只是将事件作为参数通过的手段。

最佳回答

当然,你可以围绕......通过各种活动。 也可以通过<条码>行动(OfvistaHandler),你可以做些什么。

如果你有这样的类别:

Public Class ComboBox
    Public Event SelectedIndexChanged As EventHandler   
End Class

鉴于<代码>ComboBox 之后,你可以创造补充和便利;消除手法,如:

Dim combobox1 = New ComboBox()

Dim ah As Action(Of EventHandler)
    = Sub (h) AddHandler combobox1.SelectedIndexChanged, h
Dim rh As Action(Of EventHandler)
    = Sub (h) RemoveHandler combobox1.SelectedIndexChanged, h

(无,即VB)。 NET 4.0代码,但可在3.5中使用AddressOf,并稍加 m。

因此,如果我有手稿<代码>。 Foo:

Public Sub Foo(ByVal sender as Object, ByVal e As EventArgs)
    Console.WriteLine("Over here with Foo!")
End Sub

。 我现在可以这样做:

ah(AddressOf Foo)
combobox1.Raise()
rh(AddressOf Foo)

这本书写了“在这里与Foo”的讯息。

我也可以采用这种方法:

Public Sub PassActionOfEventHandler(ByVal h As Action(Of EventHandler))
    h(AddressOf Foo)
End Sub

我可以环绕活动手行动,如:

PassActionOfEventHandler(ah)
combobox1.Raise()
PassActionOfEventHandler(rh)

这再次写“与Foo”的讯息。

现在,一个可能出现问题的问题是,你可以意外地抽出添加物并删除代号中的事件手稿——毕竟是相同的。 因此,为了添加和取消类似行动,很容易确定具有强烈类型的代表:

Public Delegate Sub AddHandlerDelegate(Of T)(ByVal eh as T)
Public Delegate Sub RemoveHandlerDelegate(Of T)(ByVal eh as T)

除代表类型外,界定代表案例的法典没有变化:

Dim ah As AddHandlerDelegate(Of EventHandler)
    = Sub (h) AddHandler combobox1.SelectedIndexChanged, h
Dim rh As RemoveHandlerDelegate(Of EventHandler)
    = Sub (h) RemoveHandler combobox1.SelectedIndexChanged, h

因此,现在让你富有创造性。 您可以确定一个职能,由增加的手递代表、除去的手递代表和一位活动管理员组成,他们将联络一名活动手,然后回到你<代码>。 IDisposable, 你可以在不需要提及活动手的情况下,日后去除手稿。 这是使用<代码>Using说明的手法。

签署:

Function SubscribeToEventHandler(
    ByVal h as EventHandler,
    ByVal ah As AddHandlerDelegate(Of EventHandler),
    ByVal rh As RemoveHandlerDelegate(Of EventHandler)) As IDisposable

因此,鉴于这一职能,我现在可以这样做:

combobox1.Raise()
Using subscription = SubscribeToEventHandler(AddressOf Foo, ah, rh)
    combobox1.Raise()
    combobox1.Raise()
End Using
combobox1.Raise()

这份信息是“与Foo”的两倍。 第一次和最后的<代码>Raise电话不属于订阅活动手。

欢乐!

问题回答

我们不能绕过事件。 它是一类,是用来改变该类活动成员状况的关键词。 在这方面,他们非常喜欢财产(已经获得并制定了方法)。

Like properties, the add and remove methods can do whatever you want. Typically, these will do nothing more than maintain a delegate instance, which itself is a MulticastDelegate or in other words, a list of delegates which are getting called one by one if the event is raised.

您可在C#中清楚地看到这一结构,在C#中,这种结构没有被贴在AddHandler/上,但你直接编辑了相关操作员名单:myObject。 活动+=新代表(......);

而且,如同财产一样,作为实际上从两种不同方法中提取的一类成员,不可能以字面上的方式将某一事件作为标的。

There are a number of different meanings for the term "event", depending upon context. In the context you are seeking, an Event is a matched pair of methods that will effectively add or remove a delegate from a subscription list. Unfortunately, there s no class in VB.NET to represent a method address without an attached object. One could probably use reflection to fetch the appropriate methods, and then pass those methods to a routine that would call them both, but in your particular situation that would probably be silly.

我能看到,通过你描述的某种活动可能是有益的唯一情况是,像 Object, whichuser to activities from long-lived Object, and which needs to unsubposition all of its activities when it is addressed. 在这种情况下,利用反省办法为每次活动寻找除去方法可能是有益的,然后在处置物体时采用所有除去方法。 不幸的是,我知道,除了描述字面外,没有办法代表要收回的事件,因为其有效性不能在时间之前加以核实。





相关问题
Is Shared ReadOnly lazyloaded?

I was wondering when I write Shared ReadOnly Variable As DataType = New DataType() Or alternatively Shared ReadOnly Variable As New DataType() Is it lazy loaded or as the instance initializes? ...

Entertaining a baby with VB.NET

I would like to write a little application in VB.NET that will detect a baby s cry. How would I get started with such an application?

Choose Enter Rather than Pressing Ok button

I have many fields in the page and the last field is a dropdown with list of values. When I select an item in a dropdown and press Enter, it doesn t do the "Ok". Instead I have to manually click on Ok ...

ALT Key Shortcuts Hidden

I am using VS2008 and creating forms. By default, the underscore of the character in a textbox when using an ampersand is not shown when I run the application. ex. "&Goto Here" is not ...

Set Select command in code

On button Click I want to Set the Select command of a Gridview. I do this and then databind the grid but it doesn t work. What am i doing wrong? protected void bttnView_Click(object sender, ...

Hover tooltip on specific words in rich text box?

I m trying to create something like a tooltip suddenly hoovering over the mouse pointer when specific words in the richt text box is hovered over. How can this be done?