Το Controls collection περιέχει όλα τα controls της φόρμας και όχι μόνο τα textboxes. Επιχειρώντας να κάνεις ένα loop σε όλα τα Controls της φόρμας σου προφανώς κάποια στιγμή συναντάς ένα Button το οποίο προσπαθεί η εφαρμογή στο runtime (implicitly) να κάνει cast σε Textbox (μια και η μεταβλητή txtBox ειναι τύπου Textbox). Φυσικά αυτό δεν γίνεται και ιδού το σφάλμα.
Αυτό που πρέπει να κάνεις είναι να εκτελέσεις κωδικα που θα παίρνει όλα τα controls της φόρμας, θα ξεχωρίζει ποιά είναι τα textboxes και θα εκτελεί μόνο σε αυτά την μέθοδο Clear(). Κάπως έτσι:
For Each ctr As Windows.Forms.Control In FormName.Controls
If (TypeOf (ctr) Is Windows.Forms.TextBox) Then
DirectCast(ctr, Windows.Forms.TextBox).Clear()
End If
Next ctr
Ορισμένες παρατηρησεις επί του κώδικα:
1. Βλέπουμε οτι στο For Each μπορούμε να ορίσουμε απευθείας τον τύπο της μεταβλητής ctr χωρίς να την έχουμε κάνει dim παραπάνω. Αυτό δεν έχει διαφορά από τη δική σου υλοποίηση, είναι όμως πιό compact ως συγγραφή.
2. H μεταβλητή ctr είναι τύπου Windows.Forms.Control. Αυτό σημαίνει οτι μπορεί να ανατεθεί σε ΟΠΟΙΟΔΗΠΟΤΕ control της φόρμας μας.
3. Στο If μας ξεχωρίζουμε μονο εκείνα τα controls που είναι τύπου Windows.Forms.Textbox. Στη συνέχεια τα κάνουμε cast στο σωστό τύπο για να μπορέσουμε να τρέξουμε την Clear(). Μην ξεχνάμε οτι το Windows.Forms.Control είναι Supertype του textbox. (Η, αλλιώς, το textbox είναι subclass του control). Χρησιμοποιούμε DirectCast και όχι Ctype μια και ειναι δεδομένο οτι έχουμε textbox και η directcast είναι σαφώς πιό γρήγορη.
Για το δεύτερο ερώτημά σου, η προσωπική μου (και όχι μόνο) άποψη είναι οτι δεν είναι σωστή προγραμματιστική τακτική. Τα modules έχουν "ξεμείνει" από την VB6 και πιό σωστό προγραμματιστικά είναι να χρησιμοποιήσεις μια Class με Shared μεθόδους ή ακόμα και μια Singleton class για να κάνεις αυτές τις δουλειές.
Σωτήρης Φιλιππίδης
DotSee Web Services