2008-10-14 9 views
21

J'ai un formulaire avec un bouton "Effacer".VB.NET - Itérer par des contrôles dans un objet conteneur

Lorsque l'utilisateur clique sur "Effacer", je souhaite effacer la valeur de tous les éléments visibles sur le formulaire. Dans le cas des contrôles de date, je veux les réinitialiser à la date actuelle.

Toutes mes commandes sont contenues dans un Panel.

En ce moment, je le fais avec le code ci-dessous. Existe-t-il un moyen plus simple que de vérifier manuellement chaque type de contrôle? Cette méthode semble excessivement lourde. Pour empirer les choses, afin d'effacer les contrôles à l'intérieur des sous-conteneurs de manière récursive (c'est-à-dire une zone de groupe dans le panneau), je dois répéter le monstre entier avec une version "GroupBox" surchargée.

Editer: Grâce à vos suggestions, le code ci-dessous est grandement simplifié.

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: J'aime votre suggestion, mais quand je change la déclaration à ceci:

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

Ensuite, cette ligne me donne « Impossible de jeter l'objet de type 'ControlCollection' taper ' ControlCollection '. ":

ClearAllControls(panMid.Controls) 

Répondre

15

Vous pouvez sauter la danse GetType et CType avec TryCast:

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

Cela va vous faire économiser environ 10 lignes.

Un extension method au large de la classe de contrôle devrait garder assez bien rangé:

<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: Si la pensée des méthodes d'extension mal qui ne tiennent pas compte NullReferenceExceptions ne vous faire grincer des dents:

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

TryCast(ctrl, CheckBox).ClearValue() 
1

J'ai fait quelque chose de similaire et c'est à peu près comme cela que je l'ai fait. La seule modification que je pourrais suggérer serait au lieu de surcharger la méthode, juste rendre le type passé dans un contrôle et vous pouvez utiliser la même version pour GroupBox, Panel, ou tout autre contrôle de conteneur qui fournit une propriété .Controls. Autre que cela, je pense que la définition de "compensation" d'un contrôle peut être quelque peu ambiguë et donc il n'y a pas de méthode Clear() appartenant à la classe Control donc vous devez implémenter ce que cela signifie pour chaque type de contrôle.

2

Pourquoi non seulement avoir une routine

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

Vous pouvez récursif nt quel que soit le niveau dans la hiérarchie, vous commencez l'appel, depuis le niveau du formulaire jusqu'à un seul conteneur.

En outre, les contrôles TextBox, j'utilise Textbox.Text = String.Empty

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

Remplacez le (CONTAINER) par le nom de la vôtre (il peut être une forme, un panneau, un GroupBox)
attention à qui vous y avez inclus vos commandes.

1

Ici, cela fonctionne pour toutes les commandes internes.
Ajoutez si d'autres contrôles doivent être supprimés.

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

ici est le code pour obtenir tout contrôle de tous les GroupControls d'un formulaire et vous pouvez faire quelque chose dans le 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 
0

Cela vient tout droit d'une article discuter des techniques à utiliser maintenant que le contrôle Les tableaux ont été supprimés en passant de 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 
0

Je vous présente mon ControlIterator classe

Source: http://pastebin.com/dubt4nPG

Quelques exemples d'utilisation:

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

Sous Raz publique (LST Comme Control.ControlCollection, récursif en option 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 
+0

appel pour mehod: raz (Me.Controls) – user3692282

+0

Essayez de ne pas afficher de code uniquement des solutions. – NathanOliver

+0

ok, mais, je pense que c'est une solution pour la question ci-dessus, n'est ce pas? – user3692282

Questions connexes