Создать и перебрать коллекцию элементов управления
Я делаю небольшое приложение 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()
Конец сабвуфера
Конец класса