VB.NET - Итерирование через элементы управления в контейнере
У меня есть форма с кнопкой "Очистить".
Когда пользователь нажимает "Очистить", я хочу очистить значение всех видимых элементов формы. В случае элементов управления датой я хочу reset их на текущую дату.
Все мои элементы управления содержатся на панели.
Сейчас я делаю это с приведенным ниже кодом. Есть ли более простой способ, чем проверка вручную для каждого типа управления? Этот метод кажется чрезмерно громоздким.
Чтобы ухудшить ситуацию, чтобы рекурсивно очистить элементы управления внутри субконтейнеров (т.е. групповой ящик внутри панели), я должен повторить весь монстр с перегруженной версией "GroupBox".
Изменить: благодаря вашим предложениям, код ниже значительно упрощен.
Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click
'User clicks Clear, so clear all the controls within this panel
ClearAllControls(panMid, True) 'True indicates that yes, i want to recurse through sub-containers
End Sub
ClearAllControls(ByRef container As Panel, Optional Recurse As Boolean = True)
'Clear all of the controls within the container object
'If "Recurse" is true, then also clear controls within any sub-containers
Dim ctrl As Control
For Each ctrl In container.Controls
If (ctrl.GetType() Is GetType(TextBox)) Then
Dim txt As TextBox = CType(ctrl, TextBox)
txt.Text = ""
End If
If (ctrl.GetType() Is GetType(CheckBox)) Then
Dim chkbx As CheckBox = CType(ctrl, CheckBox)
chkbx.Checked = False
End If
If (ctrl.GetType() Is GetType(ComboBox)) Then
Dim cbobx As ComboBox = CType(ctrl, ComboBox)
cbobx.SelectedIndex = -1
End If
If (ctrl.GetType() Is GetType(DateTimePicker)) Then
Dim dtp As DateTimePicker = CType(ctrl, DateTimePicker)
dtp.Value = Now()
End If
If Recurse Then
If (ctrl.GetType() Is GetType(Panel)) Then
Dim pnl As Panel = CType(ctrl, Panel)
ClearAllControls(pnl, Recurse)
End If
If ctrl.GetType() Is GetType(GroupBox) Then
Dim grbx As GroupBox = CType(ctrl, GroupBox)
ClearAllControls(grbx, Recurse)
End If
End If
Next
End Sub
@Theraccoonbear: Мне нравится ваше предложение, но когда я меняю объявление на это:
Private Sub ClearAllControls(ByRef controls As ControlCollection, Optional ByVal Recurse As Boolean = True)
Затем эта строка дает мне "Невозможно наложить объект типа" ControlCollection "на" ControlCollection ".":
ClearAllControls(panMid.Controls)
Ответы
Ответ 1
Вы можете пропустить танец GetType и CType с помощью TryCast:
Dim dtp as DateTimePicker = TryCast(ctrl, DateTimePicker)
If dtp IsNot Nothing then dtp.Value = Now()
Это сэкономит вам около 10 строк.
метод расширения от класса Control должен держать его довольно аккуратным:
<Extension()> _
Public Shared Sub ClearValue(c as Control, recursive as Boolean)
Dim dtp as DateTimePicker = TryCast(c, DateTimePicker)
If dtp IsNot Nothing Then dtp.Value = Now()
' Blah, Blah, Blah
End Sub
Изменить: если мысль о методах расширения Evil, игнорирующих NullReferenceExceptions, не заставит вас съежиться:
<Extension()> _
Public Shared Sub ClearValue(c as CheckBox)
If c IsNot Nothing Then c.Checked = False
End Sub
TryCast(ctrl, CheckBox).ClearValue()
Ответ 2
вот код для получения полного контроля над формой All GroupControls
и вы можете что-то сделать в элементе управления GroupBox
Private Sub GetControls()
For Each GroupBoxCntrol As Control In Me.Controls
If TypeOf GroupBoxCntrol Is GroupBox Then
For Each cntrl As Control In GroupBoxCntrol.Controls
'do somethin here
Next
End If
Next
End Sub
Ответ 3
Почему бы просто не сделать одну рутину
ClearAllControls(ByRef container As Control, Optional ByVal Recurse As Boolean = True)
Вы можете записаться на него независимо от того, какой уровень в иерархии вы начинаете, от уровня формы до одного контейнера.
Кроме того, в элементах управления TextBox я использую Textbox.Text = String.Empty
Ответ 4
Я сделал что-то подобное, и это в основном то, как я это делал. Единственное изменение, которое я мог бы предложить, было бы вместо перегрузки метода, просто сделать переданный в типе элемент управления, и вы можете использовать ту же версию для GroupBox, Panel или любого другого элемента управления контейнером, который предоставляет свойство .Controls. Помимо этого, я думаю, что определение "очистки" элемента управления может быть несколько неоднозначным и, следовательно, не существует метода Clear(), принадлежащего классу Control, поэтому вам нужно реализовать то, что это означает для ваших целей для каждого типа управления.
Ответ 5
For Each c In CONTAINER.Controls
If TypeOf c Is TextBox Then
c.Text = ""
End If
Next
Замените (КОНТЕЙНЕР) на свое имя (это может быть ФОРМА, ПАНЕЛЬ, ГРУППА)
Обратите внимание, к которым вы включили свои элементы управления.
Ответ 6
Здесь он работает для всех внутренних элементов управления.
Добавьте, если вам нужно очистить любые другие элементы управления.
Private Sub ClearAll()
Try
For Each ctrl As Control In Me.Controls
If ctrl.[GetType]().Name = "Panel" Then
ClearControls(ctrl)
End If
If ctrl.[GetType]().Name = "GroupBox" Then
ClearControls(ctrl)
End If
If ctrl.[GetType]().Name = "ComboBox" Then
Dim tb As ComboBox = TryCast(ctrl, ComboBox)
tb.SelectedText = ""
End If
If ctrl.[GetType]().Name = "TabControl" Then
ClearControls(ctrl)
End If
If ctrl.[GetType]().Name = "TextBox" Then
Dim tb As TextBox = TryCast(ctrl, TextBox)
tb.Clear()
End If
If ctrl.[GetType]().Name = "RadioButton" Then
Dim tb As RadioButton = TryCast(ctrl, RadioButton)
tb.Checked = False
End If
If ctrl.[GetType]().Name = "CheckBox" Then
Dim tb As CheckBox = TryCast(ctrl, CheckBox)
tb.Checked = False
End If
If ctrl.[GetType]().Name = "ComboBox" Then
Dim tb As ComboBox = TryCast(ctrl, ComboBox)
tb.SelectedIndex = 0
End If
If ctrl.[GetType]().Name = "RichTextBox" Then
Dim tb As RichTextBox = TryCast(ctrl, RichTextBox)
tb.Clear()
End If
Next
Catch ex As Exception
MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub ClearControls(ByVal Type As Control)
Try
For Each ctrl As Control In Type.Controls
If ctrl.[GetType]().Name = "TextBox" Then
Dim tb As TextBox = TryCast(ctrl, TextBox)
tb.Clear()
End If
If ctrl.[GetType]().Name = "Panel" Then
ClearControls(ctrl)
End If
If ctrl.[GetType]().Name = "GroupBox" Then
ClearControls(ctrl)
End If
If ctrl.[GetType]().Name = "TabPage" Then
ClearControls(ctrl)
End If
If ctrl.[GetType]().Name = "ComboBox" Then
Dim tb As ComboBox = TryCast(ctrl, ComboBox)
tb.SelectedText = ""
End If
If ctrl.[GetType]().Name = "RadioButton" Then
Dim tb As RadioButton = TryCast(ctrl, RadioButton)
tb.Checked = False
End If
If ctrl.[GetType]().Name = "CheckBox" Then
Dim tb As CheckBox = TryCast(ctrl, CheckBox)
tb.Checked = False
End If
If ctrl.[GetType]().Name = "RichTextBox" Then
Dim tb As RichTextBox = TryCast(ctrl, RichTextBox)
tb.Clear()
End If
Next
Catch ex As Exception
MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Ответ 7
Это происходит прямо из статьи , в которой обсуждаются методы использования теперь, когда контрольные массивы были устранены с перехода от VB6 к VB.NET.
Private Sub ClearForm(ByVal ctrlParent As Control)
Dim ctrl As Control
For Each ctrl In ctrlParent.Controls
If TypeOf ctrl Is TextBox Then
ctrl.Text = ""
End If
' If the control has children,
' recursively call this function
If ctrl.HasChildren Then
ClearForm(ctrl)
End If
Next
End Sub
Ответ 8
Public Sub raz(lst As Control.ControlCollection, Optional recursive As Boolean = True)
For Each ctrl As Control In lst
If TypeOf ctrl Is TextBox Then
CType(ctrl, TextBox).Clear()
End If
If TypeOf ctrl Is MaskedTextBox Then
CType(ctrl, MaskedTextBox).Clear()
End If
If TypeOf ctrl Is ComboBox Then
CType(ctrl, ComboBox).SelectedIndex = -1
End If
If TypeOf ctrl Is DateTimePicker Then
Dim dtp As DateTimePicker = CType(ctrl, DateTimePicker)
dtp.CustomFormat = " "
End If
If TypeOf ctrl Is CheckedListBox Then
Dim clbox As CheckedListBox = CType(ctrl, CheckedListBox)
For i As Integer = 0 To clbox.Items.Count - 1
clbox.SetItemChecked(i, False)
Next
End If
If TypeOf ctrl Is RadioButton Then
CType(ctrl, RadioButton).Checked = False
End If
If recursive Then
If TypeOf ctrl Is GroupBox Then
raz(CType(ctrl, GroupBox).Controls)
End If
End If
Next
End Sub
Ответ 9
Представляю вам мой ControlIterator
класс
Источник: http://pastebin.com/dubt4nPG
Некоторые примеры использования:
ControlIterator.Disable(CheckBox1)
ControlIterator.Enable({CheckBox1, CheckBox2})
ControlIterator.Check(Of CheckBox)(Me)
ControlIterator.Uncheck(Of CheckBox)(Me.GroupBox1)
ControlIterator.Hide(Of CheckBox)("1")
ControlIterator.PerformAction(Of CheckBox)(Sub(ctrl As CheckBox) ctrl.Visible = True)
ControlIterator.AsyncPerformAction(RichTextBox1,
Sub(rb As RichTextBox)
For n As Integer = 0 To 9
rb.AppendText(CStr(n))
Next
End Sub)
ControlIterator.PerformAction(Me.Controls, Sub(c As Control)
c.BackColor = Color.Green
End Sub)