Вы можете разделить создание DataTable и перечисление Controls двумя разными способами:
- Первый метод является общедоступным, который можно вызвать, просто передав родительский элемент управления, из которого начинается перечисление.
- Этот метод просто создает DataTable, затем вызывает закрытый метод, чтобы заполнить его результатами перечисления
- Приватный метод создает новый DataRow для каждого элемента управления, который находит, и добавляет его в DataTable.
Вы также можете изменить приватный метод, чтобы он возвращал список объектов, которые могут быть преобразованы в DataTable после.
Я добавил столбец с именем "Parent"
, который ссылается на родителя элемента управления. Может быть полезно узнать, кто является родителями этих контролей.
' Find all Controls in the current Form
DataGridView1.DataSource = ControlsListToDataTable(Me)
Private Function ControlsListToDataTable(parent As Control) As DataTable
If (parent Is Nothing) OrElse (Not parent.HasChildren) Then Return Nothing
Dim dt As DataTable = New DataTable("ParentControls")
dt.Columns.AddRange({
New DataColumn() With {.ColumnName = "Name", .DataType = GetType(String)},
New DataColumn() With {.ColumnName = "Type", .DataType = GetType(String)},
New DataColumn() With {.ColumnName = "Parent", .DataType = GetType(String)}
})
GetAllControls(parent, dt)
Return dt
End Function
Private Sub GetAllControls(parent As Control, dt As DataTable)
For Each ctl As Control In parent.Controls.OfType(Of Control)
dt.Rows.Add({ctl.Name, ctl.GetType().FullName, ctl.Parent.Name})
If ctl.HasChildren Then GetAllControls(ctl, dt)
Next
End Sub
Чтобы найти элемент управления в DataTable, вы можете использовать методы DataTable.DefaultView Sort и FindRows:
[DataTable].DefaultView.Sort = "Name"
Dim result = [DataTable].DefaultView.FindRows("TextBox1")
Или используйте метод LINQ:
Dim control = [DataTable].Rows.OfType(Of DataRow)().
FirstOrDefault(Function(dr) dr(0).ToString().Equals("TextBox1"))
Где [DataTable]
может быть исходной таблицей DataTable, возвращаемой публичным методом, или DataGridView.DataSource
:
Dim dt = CType(DataGridView1.DataSource, DataTable)
Dim control = dt.Rows.OfType(Of DataRow)(). (... etc ...)