如何使用/传递参数给事件处理程序?

Lab*_*abe 1 .net vb.net parameters events winforms

我已经找到了一些关于这个主题的信息,但我仍然没有完全理解它,如果有人能在我的例子中向我展示如何做到这一点,我会很高兴。

基本上,我在 VB.Net Windows 窗体应用程序中有一个充满对象的数组

Dim button(9) As cbuttons

public sub fill()
   button(1) = New cbuttons("buttonName1", 2, true)
   button(2) = New cbuttons("ButtonName2", 3, true)
   button(3) = New cbuttons("ButtonName3", 4, true)
   ...
Run Code Online (Sandbox Code Playgroud)

此数组用作按钮的源,这些按钮是动态生成的

public sub writeButtons()
    For Each item As cbutton In button

        Dim cmbDynamic As New Button()
        cmbDynamic.Location = New System.Drawing.Point(item.getX(), item.getY())
        cmbDynamic.Name = item.getname()
        cmbDynamic.Text = item.getName() & vbCrLf & item.getTypeString()
        TabPage1.Controls.Add(cmbDynamic)
        AddHandler cmbDynamic.Click, AddressOf Me.clicked 'here is the problem
Run Code Online (Sandbox Code Playgroud)

然后我有一个潜艇应该做这样的事情

public sub clicked()
  MessageBox.Show("You clicked on button " & ButtonName)
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何将按钮名称(或任何其他参数)传递给子clicked(),因为我无法向AddHalnder行添加任何参数,并且callByName()也不起作用

我正在寻找一个在 Javascript 中看起来像这样的解决方案:

  onlick="clicked(this.id)"
Run Code Online (Sandbox Code Playgroud)

谢谢

Cro*_*ono 5

该方法必须具有与Control.Click事件委托匹配的参数,在本例中为EventHandler. 因此,clicked方法需要一个Object类型参数,然后是EventArgs类型参数。

第一个参数表示发生事件的对象。因此,在处理程序中投射它时,您将能够获得它的任何属性,包括Name

Public Sub clicked(sender As Object, e As EventArgs)
    MessageBox.Show("You clicked on button " & CType(sender, Control).Name)
End Sub
Run Code Online (Sandbox Code Playgroud)

编辑:

在评论中,您询问是否可以将额外的参数传递给事件处理程序方法。对此,简短的回答是您不应该依赖这种可能性 - 特别是对于在代码库之外定义的事件。

注意:对于您自己的自定义事件,这很简单:您可以创建自己的EventArgs派生类型并将您想要的任何内容放入其中。

不过,有办法解决这个问题。您可以在类范围内存储值并在处理程序中访问它们。您可以创建一个值字典,其键是唯一标识您的按钮的东西。

一种不太优雅的方法是将信息存储在 eachButtonTag属性中。由于处理程序始终有一个Object参数表示引发事件的对象,因此您可以在其上下文中检索其任何属性。

例如,当您创建一个新Button实例时,您可以将其Tag属性设置cbutton为创建时的值:

Public Sub writeButtons()
    ' ...

    Dim cmbDynamic As New Button()
    ' ...
    cmbDynamic.Tag = item

    ' ...
End Sub
Run Code Online (Sandbox Code Playgroud)

因此,稍后,您cbutton只需执行以下操作即可恢复全部值:

Public Sub clicked(sender As Object, e As EventArgs)
    Dim btn As Button = sender
    Dim item As cbutton = btn.Tag

    MessageBox.Show("You clicked on button " & item.getname() & " which has cbutton.anyproperty equals to " & item.anyproperty)

    
End Sub
Run Code Online (Sandbox Code Playgroud)

您可以将Tag财产视为自由式存储。

忠告的话:不要滥用它。你使用的越多,你的代码就越难弄清楚。另外,如果您有多个使用它们的机制,您最终可能会在这些值中获得意想不到的值。

附加说明:

根据 .NET 约定,类型和类型成员的首选大小写是每个单词都以大写字母开头。例如,writeButtons真的应该是WriteButtons。我还应该提到以Write建议 I/O 操作开始的方法。在你的情况下,CreateButtons听起来更合适。