it-swarm.com.de

VB.NET - Iteration durch Steuerelemente in einem Containerobjekt

Ich habe ein Formular mit einer Schaltfläche "Löschen".

Wenn der Benutzer auf "Löschen" klickt, möchte ich den Wert aller sichtbaren Elemente im Formular löschen. Bei Datumskontrollen möchte ich sie auf das aktuelle Datum zurücksetzen.

Alle meine Steuerelemente befinden sich in einem Panel.

Im Moment mache ich das mit dem folgenden Code. Gibt es einen einfacheren Weg, als für jeden Steuerungstyp manuell zu prüfen? Diese Methode erscheint übermäßig unhandlich.

Um das Ganze noch schlimmer zu machen, muss ich das gesamte Monster mit einer überladenen "GroupBox" -Version wiederholen, um rekursive Steuerelemente in Untercontainern (d. H. Ein Gruppenfeld innerhalb des Bereichs) zu löschen.

Bearbeiten: Dank Ihrer Vorschläge wird der folgende Code stark vereinfacht.

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: Ich mag deinen Vorschlag, aber wenn ich die Deklaration folgendermaßen ändere:

Private Sub ClearAllControls(ByRef controls As ControlCollection, Optional ByVal Recurse As Boolean = True)

Dann wird in dieser Zeile angezeigt "Objekt des Typs 'ControlCollection' kann nicht in 'ControlCollection' umgewandelt werden.":

  ClearAllControls(panMid.Controls)
21
JosephStyons

Sie können GetType- und CType-Tanz mit TryCast überspringen:

Dim dtp as DateTimePicker = TryCast(ctrl, DateTimePicker)
If dtp IsNot Nothing then dtp.Value = Now()

Das erspart Ihnen etwa 10 Zeilen.

Eine Erweiterungsmethode off der Control-Klasse sollte es ordentlich halten:

<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

Bearbeiten: Wenn der Gedanke an Evil-Erweiterungsmethoden, die NullReferenceExceptions ignorieren, nicht zum Schrecken gebracht wird:

<Extension()> _
Public Shared Sub ClearValue(c as CheckBox)
   If c IsNot Nothing Then c.Checked = False
End Sub

TryCast(ctrl, CheckBox).ClearValue()
16
Mark Brackett

hier ist der Code, um alle Kontrolle über alle GroupControls eines Formulars zu erhalten, und Sie können im GroupBox-Steuerelement etwas tun

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
8
Imran

Warum nicht einfach eine Routine haben?

ClearAllControls(ByRef container As Control, Optional ByVal Recurse As Boolean = True)

Sie können darauf zurückgreifen, unabhängig davon, auf welcher Ebene der Hierarchie Sie den Aufruf beginnen, von der Formularebene bis zu einem einzelnen Container.

Für die TextBox-Steuerelemente verwende ich Textbox.Text = String.Empty.

2
rjrapson
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
1
user3692282

Ich habe etwas Ähnliches gemacht, und so habe ich es gemacht. Die einzige Änderung, die ich vorschlagen könnte, wäre, statt die Methode zu überladen, machen Sie einfach den übergebenen Typ zu einem Control, und Sie können dieselbe Version für GroupBox, Panel oder jedes andere Containersteuerelement verwenden, das eine .Controls-Eigenschaft bereitstellt. Abgesehen davon denke ich, dass die Definition des "Clearing" eines Steuerelements etwas mehrdeutig sein kann. Daher gibt es keine Clear () - Methode, die zur Control-Klasse gehört. Sie müssen also implementieren, was dies für Ihre Zwecke für jeden Kontrolltyp bedeutet.

1
theraccoonbear

Hier funktioniert es für alle inneren Steuerungen.
Hinzufügen, wenn andere Steuerelemente gelöscht werden müssen.

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
1
Sekhar Babu
For Each c In CONTAINER.Controls
    If TypeOf c Is TextBox Then
        c.Text = ""
    End If
Next

Ersetzen Sie den (CONTAINER) durch Ihren Namen (es kann sich um eine FORM, ein PANEL oder eine GROUPBOX handeln)
Achten Sie darauf, in welche Steuerelemente Sie Ihre Steuerelemente aufgenommen haben.

1
ShoushouLebanon

Dies kommt direkt aus einem Artikel , der Techniken diskutiert, die jetzt verwendet werden, nachdem Control Arrays nicht mehr von VB6 zu VB.NET wechseln müssen.

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
1
dmcgill50

Ich präsentiere Ihnen meine ControlIterator Klasse

Quelle: http://Pastebin.com/dubt4nPG

Einige Anwendungsbeispiele:

 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)
0
ElektroStudios