创建并循环控件的集合子集

时间:2014-11-07 14:45:38

标签: vb.net collections combobox controlcollection

我正在制作一个小的vb.net windows窗体应用程序,其中我有4个ComboBoxes。我想将ComboBox添加到集合中,并能够遍历该集合以引用每个集合。

表单上还有其他组合框,所以我不能只使用整个表单的集合(表单布局不能更改,例如添加容器等)。

我在考虑以下内容:

Public Class Form1
    Dim IoTypeCombos As New ControlCollection(Me) From {Me.IO1_ComboBox, Me.IO2_ComboBox, Me.IO3_ComboBox, Me.IO4_ComboBox}
    Dim IoTypes As New Collection() From {"Out 0", "Out 1", "Input", "Analog"}

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        For Each cb As combobox In Me.IoTypeCombos
            FillComboBox(cb, Types)
        Next
    End Sub

    Function FillComboBox(cb As Control, cc As Collection) As Boolean
        Dim cbc As ComboBox = CType(cb, ComboBox)
        If cc.Count = 0 Then
            Return False
        End If
        For Each cn In cc
            cbc.Items.Add(cn)
       Next
       Return True
    End Function

这不会引发任何异常,但它不会填充ComboBoxes :( 如果我将一个控件传递给它,FillComboBox()可以正常工作。 我究竟做错了什么?感谢

2 个答案:

答案 0 :(得分:2)

这一行是非法的:

Public Class Form1
    Dim IoTypeCombos As New ControlCollection(Me) From {Me.IO1_ComboBox, 
                Me.IO2_ComboBox, Me.IO3_ComboBox, Me.IO4_ComboBox }

该代码将在构造函数之前运行,在MeION_ComboBox存在之前。在这种情况下,生成的集合什么都没有,因为还没有任何内容。

在其他情况下,在控件存在之前引用控件可能会导致NullReference被抛出,但由于奇怪的错误,可能无法报告。当发生这种情况时,将跳过其余代码并简单显示表单。

在任何一种情况下,解决方案都是在表单级别声明您的集合,但是一旦控件存在,就在表单加载事件中填充它。我也会使用Collection(Of T)代替(数组或List(Of T)也可以工作,OP使用/询问集合):

Imports System.Collections.ObjectModel

Public Class Form1
     Dim IoTypeCombos As Collection(Of ComboBox)  ' form and controls Do No Exist yet

     Public Sub New
         '...
         InitializeComponent()
        ' NOW they exist
     End Sub

     Sub Form_Load
         IoTypeCombos = New Collection(Of ComboBox)
         IoTypeCombos.Add(IO1_ComboBox)
         IoTypeCombos.Add(IO2_ComboBox) 
         ...    

如果您使用List(Of ComboBox),则可以采用不同的方式填充:

 ' in the ctor:
 IoTypeCombos = New List(Of ComboBox)({IO1_ComboBox, IO2_ComboBox...})
 ' using AddRange:
 IoTypeCombos.AddRange({IO1_ComboBox, IO2_ComboBox...})

答案 1 :(得分:0)

不确定你是否需要where子句,但是如果你有其他没有这样名字的组合框并且不想在集合中使用它们那么你确实需要它。

Dim IoTypeComboboxes = 
    Me.Controls.OfType(Of Combobox)().Where(Function(cb) cb.Name.StartsWith("IO")).ToList()