「クリア」ボタンのあるフォームがあります。
ユーザーが[クリア]をクリックすると、フォームに表示されているすべての要素の値がクリアされます。日付コントロールの場合、現在の日付にリセットします。
私のすべてのコントロールはパネルに含まれています。
今、私はこれを以下のコードで行っています。各コントロールタイプを手動でチェックするよりも簡単な方法はありますか?この方法は過度に扱いにくいようです。
さらに悪いことに、サブコンテナ(つまり、パネル内のグループボックス)内のコントロールを再帰的にクリアするには、オーバーロードされた「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)
TryCast でGetTypeとCTypeダンスをスキップできます:
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
編集:NullReferenceExceptionsを無視するEvil拡張メソッドを考えても気が進まない場合:
<Extension()> _
Public Shared Sub ClearValue(c as CheckBox)
If c IsNot Nothing Then c.Checked = False
End Sub
TryCast(ctrl, CheckBox).ClearValue()
ここに、フォームのすべての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
なぜ1つのルーチンだけではないのですか
ClearAllControls(ByRef container As Control, Optional ByVal Recurse As Boolean = True)
呼び出しを開始する階層のレベル(フォームレベルから単一のコンテナーまで)に関係なく、再帰することができます。
また、TextBoxコントロールでは、Textbox.Text = String.Empty
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
私は似たようなことをしましたが、これは基本的に私がそれをやろうとした方法です。私が提案する唯一の変更は、メソッドをオーバーロードする代わりに、渡された型をコントロールにするだけで、GroupControl、Panel、または.Controlsプロパティを提供する他のコンテナコントロールに同じバージョンを使用できます。それ以外は、コントロールの「クリア」の定義はやや曖昧になる可能性があるため、Controlクラスに属するClear()メソッドはないため、各コントロールタイプの目的に応じてその意味を実装する必要があります。
ここでは、すべての内部コントロールに対して機能します。
他のコントロールをクリアする必要がある場合は追加します。
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
For Each c In CONTAINER.Controls
If TypeOf c Is TextBox Then
c.Text = ""
End If
Next
(CONTAINER)を自分の名前に置き換えます(フォーム、パネル、GROUPBOXの場合があります)
コントロールを含めた場所に注意してください。
これは、コントロールアレイが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
私の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)