2008-10-14 19 views
21

Tengo un formulario con un botón "Borrar".VB.NET - Iteración a través de controles en un objeto contenedor

Cuando el usuario hace clic en "Borrar", quiero borrar el valor de todos los elementos visibles en el formulario. En el caso de los controles de fecha, quiero restablecerlos a la fecha actual.

Todos mis controles están en un Panel.

En este momento, estoy haciendo esto con el siguiente código. ¿Hay una manera más fácil que verificar manualmente para cada tipo de control? Este método parece excesivamente difícil de manejar.

Para empeorar las cosas, con el fin de eliminar recursivamente los controles dentro de los sub-contenedores (es decir, un cuadro de grupo dentro del panel) tengo que repetir todo el monstruo con una versión "GroupBox" sobrecargada.

Editar: Gracias a sus sugerencias, el siguiente código se ve muy simplificado.

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: Me gusta tu sugerencia, pero cuando cambio la declaración a este:

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

Entonces esta línea me da "No se puede convertir objeto de tipo 'ControlCollection' escribir ' ControlCollection '. ":

ClearAllControls(panMid.Controls) 

Respuesta

15

puede omitir el baile GetType y CType con TryCast:

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

que usted va a ahorrar alrededor de 10 líneas.

Un extension method fuera de la clase de control debe tener bastante ordenada:

<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 

Editar: Si la idea de los métodos de extensión del mal que ignoran NullReferenceExceptions no hacen temblar:

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

TryCast(ctrl, CheckBox).ClearValue() 
1

He hecho algo similar y esto es básicamente cómo lo hice. El único cambio que podría sugerir sería en lugar de sobrecargar el método, simplemente haga que el pasado sea de tipo Control y puede usar la misma versión para GroupBox, Panel o cualquier otro control de contenedor que proporcione una propiedad .Controls. Aparte de eso, creo que la definición de "borrar" un control puede ser un tanto ambigua y, por lo tanto, no hay un método Clear() que pertenezca a la clase Control, por lo que debe implementar lo que eso significa para cada tipo de control.

2

Por qué no solo tiene una rutina

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

Puede recurse i nto independientemente del nivel de la jerarquía en que inicie la llamada, desde el nivel de formulario hasta un único contenedor.

Además, en los controles de cuadro de texto, uso Textbox.Text = String.Empty

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

Vuelva a colocar la (contenedor) con el nombre de la suya (que puede ser una forma, un panel, una caja de grupo) la atención
de pago a la que había incluido sus controles en.

1

Aquí funciona para todos los controles internos.
Agregue si tiene que borrar otros controles.

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

aquí es el código para obtener todo el control de todos GroupControls de un formulario y se puede hacer algo en el control 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

Esto viene directamente de un article discutir las técnicas para usar ahora que el Control Las matrices se han eliminado al pasar de VB6 a 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

les presento mi ControlIterator Clase

Fuente: http://pastebin.com/dubt4nPG

Algunos ejemplos de uso:

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

Public Sub Raz (LST Como Control.ControlCollection, recursiva opcional As Boolean = Verdadero)

 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

llamando a mehod: raz (Me.Controls) – user3692282

+0

Trate de no publicar soluciones de solo código. – NathanOliver

+0

bien, pero, creo que esta es una solución para la pregunta anterior, ¿no? – user3692282

Cuestiones relacionadas