22 Stimmen

VB.NET - Iterieren durch Steuerelemente in einem Container-Objekt

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 des Formulars löschen. Im Falle von Datumselementen möchte ich sie auf das aktuelle Datum zurücksetzen.

Alle meine Steuerelemente sind in einem Panel enthalten.

Im Moment mache ich das mit dem folgenden Code. Gibt es einen einfacheren Weg als die manuelle Überprüfung für jeden Kontrolltyp? Diese Methode scheint übermäßig unhandlich zu sein.

Um die Sache noch schlimmer zu machen, muss ich das ganze Monster mit einer überladenen "GroupBox"-Version wiederholen, um rekursiv Steuerelemente innerhalb von Sub-Containern zu löschen (z. B. einen Gruppenrahmen innerhalb des Panels).

Edit: Dank Ihrer Vorschläge wurde 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: Ihr Vorschlag gefällt mir, aber wenn ich die Erklärung so ändere:

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

Dann gibt diese Zeile mir "Unable to cast object of type 'ControlCollection' to type 'ControlCollection'.":

  ClearAllControls(panMid.Controls)

18voto

Mark Brackett Punkte 83046

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

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

Das spart Ihnen etwa 10 Zeilen.

Eine Erweiterungsmethode aus der Klasse Control sollte es ziemlich übersichtlich sein:

<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

Edit: Wenn der Gedanke an Evil-Erweiterungsmethoden, die NullReferenceExceptions ignorieren, Sie nicht erschaudern lässt:

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

TryCast(ctrl, CheckBox).ClearValue()

11voto

Imran Punkte 101

Hier ist der Code, um alle Steuerelemente von All GroupControls eines Formulars zu erhalten und Sie können etwas in der GroupBox Control 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

2voto

rjrapson Punkte 1967

Warum nicht nur eine Routine haben

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

Sie können unabhängig von der Hierarchiestufe, auf der Sie den Aufruf starten, von der Formularebene bis hinunter zu einem einzelnen Container rekursieren.

Außerdem verwende ich für die TextBox-Steuerelemente Textbox.Text = String.Empty

1voto

theraccoonbear Punkte 4157

Ich habe etwas Ähnliches gemacht und bin dabei im Wesentlichen so vorgegangen. Die einzige Änderung, die ich vorschlagen würde, wäre, anstatt die Methode zu überladen, einfach den übergebenen Typ zu einem Steuerelement zu machen, und Sie können die gleiche Version für GroupBox, Panel oder jedes andere Container-Steuerelement verwenden, das eine .Controls-Eigenschaft bietet. Abgesehen davon denke ich, dass die Definition des "Löschens" eines Steuerelements etwas zweideutig sein kann und daher gibt es keine Clear()-Methode, die zur Control-Klasse gehört, so dass Sie für jeden Steuerelementtyp implementieren müssen, was dies für Ihre Zwecke bedeutet.

1voto

ShoushouLebanon Punkte 11
For Each c In CONTAINER.Controls
    If TypeOf c Is TextBox Then
        c.Text = ""
    End If
Next

Ersetzen Sie (CONTAINER) durch Ihren Namen (es kann ein FORMULAR, ein PANEL, eine GROUPBOX sein)
Achten Sie darauf, wo Sie Ihre Kontrollen eingebaut haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X