Создать и перебрать коллекцию элементов управления

Я делаю небольшое приложение Windows vb.net формы, в котором у меня есть 4 ComboBox. Я хотел бы добавить 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

Это не вызывает никаких исключений, НО это также не заполняет ComboBox:(FillComboBox() отлично работает, если я передаю ему один элемент управления. Что я делаю не так? Спасибо

3 ответа

Решение

Эта строка недопустима:

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

Этот код будет выполняться до конструктора, до Me или же ION_ComboBox существовать. В этом случае результирующая коллекция не содержит ничего, поскольку в нее еще нечего положить.

В других случаях обращение к элементам управления до их появления может привести к NullReference быть брошенным, но из-за странной ошибки об этом не может быть сообщено. Когда это происходит, остальная часть кода пропускается, а форма просто отображается.

В любом случае решение состоит в том, чтобы объявить вашу коллекцию на уровне формы, но заполнить ее в событии загрузки формы, как только элементы управления существуют. Я бы также использовал коллекцию (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...})

Не уверен, что вам нужно предложение where, но если у вас есть другие выпадающие списки, у которых нет таких имен и они не нужны в коллекции, тогда вам это нужно.

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

'на yourFormName' добавлено:'45 PictureBox: ("PicBarNum1_NotLastOdig" в "PicBarNum45_NotLastOdig") 'добавлено:'45 PictureBox: ("PicBarNum1_UkOdig" в "PicBarNum45_UkOdig")

Публичный класс yourFormName

Частный picbarlistNum1to45_UkOdig как новый список (из PictureBox)

Частный picbarlistNum1to45_UkLastNotOdig как новый список (из PictureBox)

Частная подпрограмма yourFormName_Load

Вызов AddPicBoxesInList_OdigNoOdig()

Конец сабвуфера

Частная подпрограмма AddPicBoxesInList_OdigNoOdig()

picbarlistNum1to45_UkOdig.Clear()

picbarlistNum1to45_UkLastNotOdig.Clear()

picbarlistNum1to45_UkOdig = Me.Controls(0).Controls.OfType(Of PictureBox)()

.Where(Function(pb) pb.Name.StartsWith("PicBarNum") И

pb.Name.EndsWith("_UkOdig")).ToList()

picbarlistNum1to45_UkLastNotOdig = Me.Controls(0).Controls.OfType(Of

PictureBox)().Where(Function(pb) pb.Name.StartsWith("PicBarNum") И

pb.Name.EndsWith("_NotLastOdig")).ToList()

Конец сабвуфера

Конец класса

Другие вопросы по тегам