在VB.NET中从List(Of T)中引发事件

5

我已经将一个大型VB6项目移植到了VB.NET平台上,虽然它可以正确编译,但是我不得不注释掉大部分的事件处理程序,因为在winform对象中没有数组集合,所以我需要将原本放在集合数组中的各种对象放入List对象中。

例如,在VB6中,你可以拥有一个按钮数组。在我的代码中,我有:

Dim WithEvents cmdButtons As New List(Of Button) 

(在Load事件中,列表被传播)

显然,您无法在容器上触发事件。但是,是否有一种方法可以从容器内容(具有不同名称)中触发事件?

在按钮创建代码中,事件名称存在,但据我所知,处理程序不会拦截,因为Handles部分的代码不存在(已注释掉)。


请提供您代码中更多相关的部分。 - Mike Dinescu
当然。在旧的VB代码中,你会看到像Public WithEvents txtFields As TextBoxArray这样的内容。但是在VB.NET中不支持这种写法。当你使用VS2008时,它会生成一堆名为txtField_0到txtField_n的TextBoxes。这很好。然而,原始代码将遍历旧数组,并使用旧数组来触发事件。在VB.NET下,该数组不存在,因此我使用List(Of TextBox)作为数组容器。这很好并且有效,但是事件被忽略了。我正在尝试找到一种方法来使用我现有的代码触发事件。 - Nodoid
只是为了澄清一些事情:你把整个问题看反了。控件数组是一种变通方法,因为你无法创建普通的控件数组。在.NET中,这个限制已经不存在了,所以控件数组作为一种构造已经变得多余,并被移除了。正如答案所示,还可以将集合连接到事件处理程序——这是VB6不允许的另一件事情(直接来说;毕竟有一些聪明的黑客可以允许这样做)。 - Konrad Rudolph
1个回答

5

我不确定你要什么,但如果你想给容器中的某些按钮添加事件处理程序,并且还希望这些按钮在列表中被引用,你可以做如下操作:

Public Class Form1

    Dim myButtons As List(Of Button)

    Private Sub AddButtonsToList(targetContainer As Control)
        myButtons = New List(Of Button)

        For Each c In targetContainer.Controls
            If TypeOf c Is Button Then
                Dim bn = DirectCast(c, Button)
                AddHandler bn.Click, AddressOf SomeButton_Click
                myButtons.Add(bn)
            End If
        Next
    End Sub

    Private Sub SomeButton_Click(sender As Object, e As EventArgs)
        Dim bn = DirectCast(sender, Button)
        MsgBox("You clicked " & bn.Name)
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' GroupBox1 has some Buttons in it
        AddButtonsToList(GroupBox1)
    End Sub

End Class

1
看起来正是我想要的。目前,我在加载中使用了myButtons.AddRange(New Buttons() {_btn_0, _btn_1, _btn_2})。我会在addRange之后添加一个foreach来添加处理程序。谢谢 :) - Nodoid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接