2008-10-14 12 views
21

Mam formularz z przyciskiem "Wyczyść".VB.NET - Iterowanie za pomocą kontrolek w obiekcie kontenerowym

Gdy użytkownik kliknie "Wyczyść", chcę wyczyścić wartość wszystkich widocznych elementów w formularzu. W przypadku kontroli daty chcę zresetować je do bieżącej daty.

Wszystkie moje elementy sterujące znajdują się na panelu.

W tej chwili robię to z poniższym kodem. Czy istnieje łatwiejszy sposób niż ręczne sprawdzanie dla każdego typu kontrolki? Ta metoda wydaje się nadmiernie nieporęczna.

Na domiar złego, aby rekurencyjnie wyczyścić kontrole wewnątrz podkonteneli (tj. Pole grupy w panelu), muszę powtórzyć cały potwór z przeciążoną wersją "GroupBox".

Edytuj: Dzięki Twoim sugestiom poniższy kod jest znacznie uproszczony.

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: Lubię swoje sugestie, ale kiedy zmienić deklarację do tego:

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

Potem linia ta daje mi „Nie można rzutować obiektu typu«ControlCollection»wpisać" ControlCollection '. ":

ClearAllControls(panMid.Controls) 

Odpowiedz

15

można pominąć taniec gettype i CType z TryCast:

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

że będziesz zaoszczędzić około 10 wierszy.

extension method off klasy kontrolne powinny zachować ładny schludny:

<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 

Edycja: Jeśli myśl o szatańskich metod rozszerzeń, które ignorują NullReferenceExceptions nie sprawi, że warować:

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

TryCast(ctrl, CheckBox).ClearValue() 
1

Zrobiłem coś podobnego i to jest zasadniczo to, w jaki sposób to zrobiłem. Jedyna zmiana, którą mógłbym zasugerować, to zamiast przeciążać tę metodę, wystarczy, że przekażesz typowi Kontrolkę i możesz użyć tej samej wersji dla GroupBox, Panel lub dowolnego innego kontrolera kontenera, który zapewnia właściwość .Controls. Poza tym, myślę, że definicja "wyczyszczenia" kontrolki może być nieco niejednoznaczna i dlatego nie ma metody Clear() należącej do klasy Control, więc musisz zaimplementować to, co to oznacza dla twoich celów dla każdego typu kontrolnego.

2

Dlaczego nie tylko masz jedną rutynę, ale możesz powtórzyć i nto niezależnie od poziomu w hierarchii, od którego zaczynasz wywoływanie, od poziomu formularza do pojedynczego kontenera.

Również na formantów TextBox, używam Textbox.Text = String.Empty

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

Wymienić (kontener) o nazwie twoje (może to być forma, panel, groupbox)
zwrócić uwagę na który włączyłeś formanty.

1

Tutaj działa dla wszystkich wewnętrznych elementów sterujących.
Dodaj, jeśli chcesz usunąć inne kontrolki.

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

Oto kod, aby uzyskać wszystkie kontrolę nad formą wszystko GroupControls i można zrobić coś w sterowaniu 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

ten pochodzi prosto z article omawianie technik użyć teraz, że kontrola Tablice zostały usunięte przy przechodzeniu z VB6 na 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

Przedstawiam wam mój ControlIterator Klasa

Źródło: http://pastebin.com/dubt4nPG

Niektóre przykłady użycia:

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 Jak Control.ControlCollection opcjonalnie rekurencyjne 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

dzwoń do mehod: raz (Me.Controls) – user3692282

+0

Staraj się nie publikować rozwiązań tylko kodu. – NathanOliver

+0

ok, ale myślę, że jest to rozwiązanie dla powyższego pytania, prawda? – user3692282

Powiązane problemy