Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Sub CleanTextBoxes

Îåêßíçóå áðü ôï ìÝëïò Αλέξανδρος Δημητρίου. Τελευταία δημοσίευση από το μέλος Αλέξανδρος Δημητρίου στις 20-10-2007, 22:09. Υπάρχουν 10 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  20-10-2007, 14:06 36416

    Sub CleanTextBoxes

    Παιδιά Καλημέρα...

    Θελω να φτιάξω μια υπορουτίνα η οποία κατά το άνοιγμα της φόρμας θα καθαρίζει όλα τα textboxes.έχω κάνει το εξής:

    Σε ένα Module έχω φτιάξει την εξής υπορουτίνα:

    Public Sub CleanTextBoxes(ByVal FormName As Windows.Forms.Form)

    Dim txtBox As TextBox

    For Each txtBox In FormName.Controls

    txtBox.Clear()

    Next txtBox

    End Sub

     

    Στο load event της φόρμας μου τρέχω το εξής:

    call Cleantextboxes(me)     και παίρνω το παρακάτω λάθος:

    Unable to cast object of type 'System.Windows.Forms.Button' to type 'System.Windows.Forms.TextBox'.

     

    1)Θα μου πει κάποιος σας παρακαλώ γιατι?

    2)Ειναι σωστό προγραμματιστικά να χρησιμοποιεις modules και να καλείς διαδικασίες απο εκει?

     

     

    Ευχαριστώ πολυ παιδιά

     


    Αυτοί που ζουν γενναίοι είναι ενάρετοι,κάνουν ένδοξες πράξεις και πέθαινουν αιώνια ξακουστοί....
    Μ.Αλέξανδρος...IV Crusade...
  •  20-10-2007, 18:52 36426 σε απάντηση της 36416

    Απ: Sub CleanTextBoxes

    Το 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

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  20-10-2007, 18:56 36427 σε απάντηση της 36416

    Απ: Sub CleanTextBoxes

    Καταρχήν, δεν υπάρχει κανένας λόγος να καθαρίσεις τα textbox γιατί είναι κενά εξαρχής. Υποψιάζομαι ότι προσπαθείς να ξαναχρησιμοποιήσεις την ίδια μεταβλητή φόρμας ή αντί να δημιουργήσεις ένα instance της φόρμας (π.χ. Dim myForm As New Form1()) χρησιμοποιείς το όνομα της φόρμας (Form1.Show()). Αυτός ο τρόπος μπορεί να σου δημιουργήσει πολλά προβλήματα. Εϊναι πολύ καλύτερο να δημιουργείς ένα νέο instance όταν θέλεις να δείξεις τη φόρμα. Επίσης, είναι λάθος να χρησιμοποιείς modules. Αν έχεις μία μέθοδο η οποία επηρεάζει μόνο μία φόρμα, θα πρέπει να είναι μέθοδος της φόρμας, όχι να βρίσκεται σε κάποιο module. Το ίδιο ισχύει και για τις κλάσεις. Η κάθε κλάση ή φόρμα είναι υπεύθυνη για τον εαυτό της και θα πρέπει μόνο αυτή να τροποποιεί τα πεδία της. Όταν θέλεις π.χ. από μία φόρμα να τροποποιήσεις τα πεδία μίας άλλης, θα πρέπει να φτιάξεις μία μέθοδο στην άλλη φόρμα η οποία θα κάνει αυτή τη δουλειά.

    Από εκεί και πέρα, ο λόγος που ο κώδικας σου δεν δουλεύει είναι ότι το Controls collection περιέχει όλα τα control της φόρμας, όχι μόνο τα TextBox. Έτσι όπως έχεις γράψει τον κώδικα λες ουσιαστικά, για κάθε control της φόρμας, κάνε το μου cast σε TextBox και μετά κάλεσε την Clear. Το αποτέλεσμα είναι ο κώδικας να ρίξει το exception που πήρες μόλις συνάντησε ένα control το οποίο δεν ήταν TextBox.
    Αντί να χρησιμοποιείς μία μεταβλητή TextBox για το For Each θα πρέπει να χρησιμοποιήσεις μία τύπου Control. Μετά, μέσα στο loop, ελέγχεις τον τύπο της μεταβλητής και αν είναι TextBox καλείς την Clear. Επίσης, δεν πρέπει να ορίζεις την μεταβλητή πριν το For Each γιατί έτσι θα κρατήσεις ένα reference στο τελευταίο control της φόρμας μέχρι να τελειώσει η εκτέλεση της μεθόδου σου. Καλύτερα να γράψεις

    For Each myContol As Control in myForm.Controls
       Dim myTextBox as TextBox=TryCast(myControl,TextBox)
       If myControl Is Nothing Then
           myTextBox.Clear()
       End If

    Next


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  20-10-2007, 18:58 36429 σε απάντηση της 36427

    Απ: Sub CleanTextBoxes

    Μαλλον Παναγιώτη έγραφες τα ίδια πράγματα την ώρα που έγραφα κι εγώ :) Να πω οτι όντως το θέμα με το reference στο τελευταίο στοιχείο δεν το σκέφτηκα, και είναι σωστό. Αρα είναι ΚΑΙ από άποψη resource allocation καλύτερο το for each x as.

     


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  20-10-2007, 19:58 36431 σε απάντηση της 36429

    Απ: Sub CleanTextBoxes

    Παιδιά πήρα δυο καλές διαφωτισικές απαντήσεις

    Είστε άψογοι , Ευχαριστώ για το χρόνο σας....


    Αυτοί που ζουν γενναίοι είναι ενάρετοι,κάνουν ένδοξες πράξεις και πέθαινουν αιώνια ξακουστοί....
    Μ.Αλέξανδρος...IV Crusade...
  •  20-10-2007, 20:13 36432 σε απάντηση της 36431

    Απ: Sub CleanTextBoxes

    Αντιγράφω από τους κανονισμούς:

    Αν λάβουμε απάντηση που μας λύνει το πρόβλημα, είναι πολύ σημαντικό να θέσουμε σε "Έχει επιλυθεί" το "Κατάσταση Ενότητας" και να μαρκάρουμε τη σωστή απάντηση με το "Σημείωση ως Απάντησης". Είναι πιο σημαντικό από "χίλια ευχαριστώ", από το να ανάψετε λαμπάδα ίσα με το μπόι αυτού που σας απάντησε (που να το ξέρετε άλλωστε;) ή να του στείλετε ένα τενεκέ λάδι. Έτσι, και θα σας μείνει ο τενεκές και δε θα σας λένε οι υπόλοιποι χρήστες τενεκέ.

    :)


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  20-10-2007, 21:16 36435 σε απάντηση της 36432

    Απ: Sub CleanTextBoxes

    Φίλε Παναγιώτη το δικό σου παράδειγμα δε λειτουργεί.Είναι σαν να μη κάνει απολύτως τίποτα. Το έτρεξα με steps και δεν μπαίνει καθόλου στη συνθήκη.ανεστρεψα τη συνθήκη και όταν μπαίνει μέσα σε αυτή χτυπά null referece exception. Το παράδειγμα του cap δουλέυει άψογα.Παρ'ολα αυτα έχω πρόβλημα με τα textboxes που είναι μέσα σε groupBoxes. Δεν τα επηρεάζει καθόλου. Τι να κάνω για αυτό?


    Αυτοί που ζουν γενναίοι είναι ενάρετοι,κάνουν ένδοξες πράξεις και πέθαινουν αιώνια ξακουστοί....
    Μ.Αλέξανδρος...IV Crusade...
  •  20-10-2007, 21:35 36436 σε απάντηση της 36435

    Απ: Sub CleanTextBoxes

    Για να χειριστείς controls που βρίσκονται μέσα σε άλλα controls συνήθως χρειάζεται να υλοποιήσεις αναδρομικότητα (μια μέθοδο που να καλεί τον εαυτό της). Το groupbox είναι ένα control που περιέχει controls. Παραθέτω το σχετικό κώδικα:

    Public Overloads Sub CleanTextBoxes(ByVal FormName As Windows.Forms.Form)

    For Each ctr As Windows.Forms.Control In FormName.Controls
    CleanTextBoxes(ctr)
    Next

    End Sub


    Public Overloads Sub CleanTextBoxes(ByVal givenControl As Windows.Forms.Control)
    If (TypeOf (givenControl) Is Windows.Forms.TextBox) Then
    DirectCast(givenControl, Windows.Forms.TextBox).Clear()
    Else
    For Each ctr As Windows.Forms.Control In givenControl.Controls
    CleanTextBoxes(ctr)

    Next ctr
    End If
    End Sub

    Οπως βλέπεις έχουμε δύο μεθόδους με το ίδιο όνομα, με το χαρακτηριστικό "Overloads" αυτές είναι overloaded methods, που σημαίνει οτι διαφέρουν στα ορίσματα (παραμέτρους). Η πρώτη δέχεται ως όρισμα μια φόρμα και εξετάζει ένα - ένα τα controls της περνώντας το χειρισμό στη δεύτερη. Η δεύτερη κοιτάει αν το control που εξετάζουμε είναι textbox, οπότε το καθαρίζει, διαφορετικά προσπαθεί να μπεί στα controls του control καλώντας τον εαυτό της. (Αν το control δεν έχει άλλα controls προφανώς δεν θα γίνει τίποτα). Οταν καλεί τον εαυτό της για τα controls που περιέχονται μέσα στο groupbox, κοιτάει και πάλι ποιά από αυτά είναι textboxes και συνεχίζει, μέχρι να μην έχουμε άλλα controls μέσα σε controls. Είναι αυτονόητο οτι αυτή η αναδρομικότητα δουλεύει για απεριόριστο βάθος, ήτοι μπορεις να εχεις groupboxes μέσα σε groupboxes μέσα σε groupboxes και στο τελευταίο επίπεδο να έχεις ένα textbox.


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  20-10-2007, 21:57 36439 σε απάντηση της 36427

    Απ: Sub CleanTextBoxes

    Παναγιώτης Καναβός:
    Καταρχήν, δεν υπάρχει κανένας λόγος να καθαρίσεις τα textbox γιατί είναι κενά εξαρχής.

    Τώρα το είδα αυτό!

    Αποκλείεις να έχουν τιμές "καρφωτά";


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  20-10-2007, 21:57 36440 σε απάντηση της 36435

    Απ: Sub CleanTextBoxes

    Ουπς, έπρεπε να γράψω Not myTextBox Is Nothing. Αλλά γιατί επιμένεις να καθαρίσεις τα TextBoxes? Αφού δεν χρειάζεται. Είναι κακή ιδέα να προσπαθείς να ξαναχρησιμοποιήσεις μία φόρμα. Πολύ κακή.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  20-10-2007, 22:09 36441 σε απάντηση της 36440

    Απ: Sub CleanTextBoxes

    Θα σου απαντήσω γιατί καθαρίζω τα textboxes.......

    Ειμαι στη φόρμα καταχώρησης πελατών.καταχωρώ ένα πελάτη με κάποια procedure.Τα πεδία μου όμως μένουν με τις τελευταίες εγγραφές.Οπότε Θέλω πατώντας το κουμπί αποθήκευση να τα καθαρίσω για να εισάγω επόμενο πελάτη εάν χρειαστεί

    Δεν κάνω στα πεδία μου databinding...Tα έχω κενά και έπειτα τρέχω procedures για τους παρακάτω λόγους

    1)όταν ένα textbox κανει databinding σε αριθμητικό πεδίο πίνακα βάσης sql όταν πέσεις πάνω σε αυτό το πεδίο με tab δε σε αφήνει να φύγεις άμα δε βάλεις αριθμό.

    2) Δεν έχω καταφέρει ακόμα να στείλω null τιμή στη βάση μου.Όταν ένα textbox είναι κενό στέλνει τη τιμή ΄΄ στη βάση μου , οπότε το χειρίζομαι ως εξής:

    Στη procedure γράφω:

    If @Custaddress = '' Set @Custaddress = Null

    Ξέρω οτι υπαρχουν τρόποι μα δε ξέρω ποιοί!Κι εκεί έρχεται η πολύτιμη βοήθειά σας καθώς και τα books on line τα οποία κατά την άποψη μου μπερδεύουν πάρα πολύ.Όχι τόσο του sql όσο της Vis Studio.

    Παιδιά αν μπορείτε ρίξτε μια ματιά και στο άλλο θέμα που έχω εκθέσει.Έιναι ακόμα πιο σημαντικό.Εδώ το πολυ πολυ κάνεις τα πεδία clean και ένα - ενα.....

     

    Παιδια κ πάλι ευχαριστώ.........


    Αυτοί που ζουν γενναίοι είναι ενάρετοι,κάνουν ένδοξες πράξεις και πέθαινουν αιώνια ξακουστοί....
    Μ.Αλέξανδρος...IV Crusade...
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems