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

 

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

Refresh του Grid της Parent form

Îåêßíçóå áðü ôï ìÝëïò pap. Τελευταία δημοσίευση από το μέλος infoCENTER στις 01-06-2010, 02:59. Υπάρχουν 12 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  03-05-2010, 17:29 58498

    Refresh του Grid της Parent form

    Έχω ένα προβληματάκι...

    Εχω μια Main (parent) φόρμα fMain και θέλω να εισάγω μια καινούργια εγγραφή από μια άλλη φόρμα π.χ. fInsert. Η τελευταία είναι modeless form και στην ουσία ο σκοπός μου είναι με το που πατήσει Save ο χρήστης να εισαχθεί η εγγραφή στο grid της fMain και να φανεί την ίδια στιγμή που πάτησε Save.


    Αυτό που έχω γράψει στην fInsert είναι το εξής:
    ContactRepository contactRepository = new ContactRepository();
    DataTable dtContacts = null;
    string surname = "";
    string firstname = "";
    string city = "";
    string address = "";
    string mobilephone = ""; string homephone = ""; dtContacts = (((this.Owner as fMain).Controls["ucContactsGrid"].Controls["gridControl"] as DevExpress.XtraGrid.GridControl).DataSource as DataTable); surname = textEditSurname.Text.Trim(); firstname = textEditFirstname.Text.Trim(); city = textEditCity.Text.Trim(); address = textEditAddress.Text.Trim(); mobilephone = textEditMobilephone.Text.Trim(); homephone = textEditHomephone.Text.Trim(); // εισαγωγή στο Grid για να φανεί η εισαγωγή dtContacts.Rows.Add(new object[] { surname, firstname, city, address, mobilephone, homephone }); // εισαγωγή στη database contactRepository.Insert(textEditSurname.Text, textEditFirstname.Text, textEditCity.Text, textEditAddress.Text, textEditMobilephone.Text, textEditHomephone.Text);


    H προτελευταία εντολή μου πετάει NullReferenceException. Καμμιά λύση/άλλη εκδοχή;
  •  03-05-2010, 19:51 58504 σε απάντηση της 58498

    Απ: Refresh του Grid της Parent form

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

    1. Θα μπορούσες να περνάς την φόρμα που κάλεσε την Insert σαν παράμετρο στον constructor της Insert και από εκεί να καταχωρείς την εγγραφή όπως ήδη το κάνεις.

    2. Θα μπορούσες αντί της φόρμας να περνάς σαν παράμετρο το BindingSource που θα έχεις φτιάξει επάνω στην Main. Αν κατάλαβα καλά το Binding που έχεις κάνει είναι DataTable -->Grid. Θα μπορούσε να ήταν DataTable --> BindingSource --> Grid. Βασικά από την πρώτη προτιμώ την δεύτερη λύση.

    3. Θα μπορούσες να έχεις μία κλάση ή κλάσεις που να κρατάνε τα δεδομένα της εφαρμογής και οι οποίες θα γινόντουσαν Reference από όλες τις φόρμες σου. Αν τις έχεις φτιάξει και με singleton pattern τότε δεν θα χρειαζόταν να περαστούν και σαν παράμετροι στα constructors των φορμών. Η λύση αυτή την θεωρώ ακόμα καλύτερη από την 2.

    Για τον κώδικα τώρα που είδα επέτρεψέ μου να σου κάνω μία μικρή παρατήρηση η οποία θα σε σώσει από πάρα πολύ χρόνο. Πρόσεξα ότι στην φόρμα σου αναφέρεσαι σε κάθε control για να πάρεις την τιμή του. Με την χρήση ενός BindingSource αυτό δεν θα χρειαζόταν να το κάνεις. Το κάνει αυτόματα το BindingSource και ενημερώνει το αντίστοιχο DataRow που του έχεις περάσει.

     

  •  03-05-2010, 21:17 58507 σε απάντηση της 58504

    Απ: Refresh του Grid της Parent form

    Yes +++
  •  05-05-2010, 00:32 58544 σε απάντηση της 58507

    Re: Απ: Refresh του Grid της Parent form

    Για το μήνυμα λάθους το μόνο που μου λέει είναι ότι δεν έχει γίνει allocate το αντικείμενο. Ως εναλλακτική κάτι γρήγορο που σκέφτομαι είναι να περάσεις από τον constructor της Form ένα Action το οποίο θα λέγεται OnSuccessContinuation, και θα κάνει this.Refresh ξέρω γω. Οπότε όταν το save σου γίνει επιτυχώς, κάνεις invoke to Action και είσαι οκ.

    Αν κατάλαβα καλά τι ζήτησες, αν όχι, post.Dispose();

    Big Smile

    https://twitter.com/biboudis
  •  10-05-2010, 14:41 58616 σε απάντηση της 58504

    Απ: Refresh του Grid της Parent form

    infoCENTER:

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

    1. Θα μπορούσες να περνάς την φόρμα που κάλεσε την Insert σαν παράμετρο στον constructor της Insert και από εκεί να καταχωρείς την εγγραφή όπως ήδη το κάνεις.

    2. Θα μπορούσες αντί της φόρμας να περνάς σαν παράμετρο το BindingSource που θα έχεις φτιάξει επάνω στην Main. Αν κατάλαβα καλά το Binding που έχεις κάνει είναι DataTable -->Grid. Θα μπορούσε να ήταν DataTable --> BindingSource --> Grid. Βασικά από την πρώτη προτιμώ την δεύτερη λύση.

    3. Θα μπορούσες να έχεις μία κλάση ή κλάσεις που να κρατάνε τα δεδομένα της εφαρμογής και οι οποίες θα γινόντουσαν Reference από όλες τις φόρμες σου. Αν τις έχεις φτιάξει και με singleton pattern τότε δεν θα χρειαζόταν να περαστούν και σαν παράμετροι στα constructors των φορμών. Η λύση αυτή την θεωρώ ακόμα καλύτερη από την 2.

    Για τον κώδικα τώρα που είδα επέτρεψέ μου να σου κάνω μία μικρή παρατήρηση η οποία θα σε σώσει από πάρα πολύ χρόνο. Πρόσεξα ότι στην φόρμα σου αναφέρεσαι σε κάθε control για να πάρεις την τιμή του. Με την χρήση ενός BindingSource αυτό δεν θα χρειαζόταν να το κάνεις. Το κάνει αυτόματα το BindingSource και ενημερώνει το αντίστοιχο DataRow που του έχεις περάσει.

     



    Ευχαριστώ για τη βοήθειά σας όλους. Με το Singleton pattern εννοείς τις κλάσεις που έχουν να κάνουν με τα δεδομένα της βάσης (Contacts);
  •  11-05-2010, 18:15 58638 σε απάντηση της 58616

    Απ: Refresh του Grid της Parent form

    Δεν μπορώ να πω ότι κατάλαβα ακριβώς τι με ρωτάς αλλά θα κάνω μία προσπάθεια να εξηγήσω. Αναφέρεσαι στην τρίτη λύση που έγραψα οπότε θα περιγράψω τι θέλω να πω.

    Σχεδόν όλες οι εφαρμογές δημιουργούνται για να διαχειριστιούν δεδομένα κάποια μορφής, που συνήθως βρίσκονται σε μία εξωτερική πηγή π.χ σε μία βάση δεδομένων. Όταν λοιπόν γράφεις των κώδικα για να διαβάσεις τα δεδομένα από την εξωτερική πηγή θα πρέπει κάπου μέσα στην εφαρμογή σου να τα κρατήσεις για να τα δείξεις στον χρήση. Συνήθως τα κρατάς στο επίπεδο της φόρμας. Δηλαδή ο κώδικας ανάκτησης των δεδομένων, κράτησης σε μία μεταβλητή και εμφάνισης είναι στην ίδια κλάση, δηλαδή της φόρμας που τα εμφανίζει.

    Ίσως να έχεις ακούσει τον όρο DAL (Data Access Layer). Ουσιαστικά ο όρος αυτός αναφέρεται στον κώδικα ανάκτησης των δεδομένων αλλά και αποθήκευσης, όμως εδώ θα μιλήσουμε μόνο για την ανάκτηση. Αν το έχεις ακούσει τότε λογικά θα έχεις δημιουργήσει μία κλάση στην οποία έχεις βάλει τον κώδικα που θα διαβάζει τα δεδομένα από την βάση. Και θα το έχεις κάνει γιατί ίσως να σου άρεσε η ιδέα να ξεχωρίσεις τον κώδικα που εμφανίζει δεδομένα στον χρήστη με αυτό που τα διαβάζει από μία εξωτερική πηγή είτε γιατί σου είναι πιο εύκολη η διαχείριση και η συντήρηση του κώδικά σου. Όπως και να έχει χωρίς να το ξέρεις ακολούθησες μέχρι ένα σημείο μία από τις οδηγίες του αντικειμενοστραφούς προγραμματισμού. Κάθε κλάση θα πρέπει να κάνει ένα πράγμα και μόνο ένα πράγμα. Οπότε είχες μία κλάση που περιείχε κώδικα για την εμφάνιση του UI, κώδικα για την διαχείριση των δεδομένων και κώδικα για την ανάκτηση των δεδομένων. Με το παραπάνω βήμα έβγαλες των κώδικα ανάκτησης των δεδομένων από την κλάση αυτή.

    Οπότε στην αρχική κλάση μας μένει ο κώδικας εμφάνισης του UI στον χρήστη και της διαχείρισης των δεδομένων. Η τρίτη λύση που πρότεινα ουσιαστικά βγάζει από την κλάση αυτή των συγκεκριμένο κώδικα διαχείρησης και τον βάζει σε μία άλλη. Ουσιαστικά μιλάω για Data Models και για Buziness Models. Οπότε ναι αναφέρομαι στα δεδομένα σου που πέρνεις από την βάση.

    To Singleton Pattern όμως δεν έχει να κάνει με τα δεδομένα αλλά με τον τρόπο που θα δημιουργήσεις ένα instance μίας οποιασδήποτε κλάσης και πως αυτό το instance θα μπορεί να γίνει access από οποιοδήποτε σημείο του κώδικά σου χωρίς να έχεις reference στο instance αυτό. Πληροφορίες μπορείς να βρεις στο internet για αυτό ή στο ελληνικό site http://www.designpatterns.gr/singleton (Μετάφραση Σόλο.... γκρρρρρ........). Επειδή λοιπόν κάθε φόρμα που θα φτιάξεις στην εφαρμογή σου θα έχει να κάνει κάποια εργασία με τα δεδομένα από την βάση, θα πρέπει με κάποιο τρόπο να έχεις πρόσβαση στην κλάση που κρατάει στα δεδομένα αυτά. Αυτό μπορεί να γίνει με δύο τρόπους. Είτε να περνάς ένα Reference σε κάθε φόρμα που θα εμφανίζεις, είτε με την χρήση του Pattern, χωρίς να περνάς reference να έχεις πρόσβαση στο instance που κρατάει τα δεδομένα. ΄

    Τώρα πάλι μπορεί να είμαι τελείος εκτός από αυτό που ρώτησες αλλά είχα λίγη ώρα και είπα να προσπαθήσω να απαντήσω. Αυτό όμως που μου προκαλεί εντύπωση είναι που δεν με ρώτησες για το BindingSource που σου είπα στο τέλος... Εκτός και αν το βρήκες, γιατί πίστεψέ με θα σε γλυτώσει από πάρα πολύ χρόνο, φαντάσου η φόρμα αυτή αντί 6 πεδία να είχε 25...

     

  •  18-05-2010, 13:23 58723 σε απάντηση της 58638

    Απ: Refresh του Grid της Parent form

    infoCENTER ευχαριστώ που αφιερώνεις τόσο χρόνο για να γράψεις αναλυτικά πάνω στην απορία μου. Λοιπόν παραθέτω κώδικα να δεις πως χρησιμοποιώ το Singleton pattern στην εφαρμογή μου ώστε να αποφανθείς αν το χρησιμοποιώ σωστά.

    public class ContactRepository
    {
        private OleDbDataAdapter _contactDataAdapter;
        private OleDbCommand _selectCommand;
        private OleDbCommand _insertCommand;
        private OleDbConnection _connection;
        private DataSet _contactDataset;
    
        private static readonly ContactRepository _instance = new ContactRepository();
    
    private ContactRepository()
    {
        _contactDataAdapter = new OleDbDataAdapter();
        _contactDataset = new DataSet();
        _connection = new OleDbConnection(App.GetConnectionString());
    
       if (_connection.State == ConnectionState.Closed)
            _connection.Open();
    
        _contactDataAdapter.SelectCommand = new OleDbCommand("SELECT surname, firstname, city, address, mobilephone, homephone FROM Contact", _connection);
        _contactDataAdapter.InsertCommand = new OleDbCommand(@"
                    INSERT INTO Contact(surname, firstname, city, address, mobilephone, homephone)
                    VALUES (@surname, @firstname, @city, @address, @mobilephone, @homephone)", _connection);
         _contactDataAdapter.InsertCommand.Parameters.Add("@surname", OleDbType.VarChar, 50, "surname");
        _contactDataAdapter.InsertCommand.Parameters.Add("@firstname", OleDbType.VarChar, 50, "firstname");
        _contactDataAdapter.InsertCommand.Parameters.Add("@city", OleDbType.VarChar, 50, "city");
        _contactDataAdapter.InsertCommand.Parameters.Add("@address", OleDbType.VarChar, 50, "address");
        _contactDataAdapter.InsertCommand.Parameters.Add("@mobilephone", OleDbType.VarChar, 10, "mobilephone");
        _contactDataAdapter.InsertCommand.Parameters.Add("@homephone", OleDbType.VarChar, 10, "homephone");
        _contactDataAdapter.Fill(_contactDataset, "Contact");
        _connection.Close();
    }
    
    public static ContactRepository GetContactRepository()
    {
        return _instance;
     }
    
    public DataTable GetDataSource()
    {
        return _contactDataset.Tables["Contact"];
    }
    
    public void Insert(string surname, string firstname, string city, string address, string mobilephone, string homephone)
    {
            if (_connection.State == ConnectionState.Closed)
                _connection.Open();
    
            _contactDataAdapter.InsertCommand.Parameters["@surname"].Value = surname;
            _contactDataAdapter.InsertCommand.Parameters["@firstname"].Value = firstname;
            _contactDataAdapter.InsertCommand.Parameters["@city"].Value = city;
            _contactDataAdapter.InsertCommand.Parameters["@address"].Value = address;
            _contactDataAdapter.InsertCommand.Parameters["@mobilephone"].Value = mobilephone;
            _contactDataAdapter.InsertCommand.Parameters["@homephone"].Value = homephone;
            _contactDataAdapter.InsertCommand.ExecuteNonQuery();
            _connection.Close();
    }
    Έχω δηλαδή τον constructor, την GetContactRepository()που επιστρέφει το Instance, την GetDataSource() που γίνεται bind με ένα Datagrid και την Insert που καταχωρεί μία εγγραφή στη βάση.

    Τέλος, όσο για το BindingSource, το ψάχνω για να δω ακριβώς πως δουλεύει, οπότε χρειάζομαι και λίγη βοήθεια Smile.
  •  18-05-2010, 15:28 58726 σε απάντηση της 58723

    Απ: Refresh του Grid της Parent form

    Και άλλος με C# (γκρρρ.... :)

    Δεν γνωρίζω καλά C# αλλά αν η δήλωση static είναι η αντίστοιχη της shared στην VB τότε το έχεις υλοποιήση μια χαρά.

    Όσο για το BindingSource. Βασικά είναι ένα control το οποίο δεν φαίνεται επάνω στην φόρμα αλλά στο κάτω μέρος αυτής. Χρησιμοποιείτε αποκλειστικά για Binding σενάρια και έχει μερικά πολύ χρήσιμα properties. Ένα κλασσικό σενάριο Binding θα ήταν π.χ Grid control --> DataTable. Το BindingSource έρχεται και μπαίνει ενδιάμεσα. Grid control --> BindingSource --> DataTable. Πως γίνεται αυτό. Δημιουργείς το DataTable σου κανονικά στην φόρμα, εφόσων παίζεις με DataTables. Ρίχνεις ένα BindingSource επάνω στην φόρμα και βάζεις το DataSource property να βλέπει το DataTable. Στην συνέχεια βάζεις το DataSource property του Grid να βλέπει το BindingSource. Η ίδια διαδικασία γίνεται αυτόματα από το VS αν έχεις περάσει το Datatable σαν DataSource στο project σου και το κάνεις Drag 'n Drop στην φόρμα.

    Τώρα μέχρι το σημείο αυτό δεν βλέπεις να έχεις κερδίσει κάτι σε σχέση με τον προηγούμενο τρόπο, πάμε όμως να δούμε τι μας δίνει αυτό το νέο control. Ας υποθέσουμε ότι ο χρήστης έχεις επιλέξει μία εγγραφή από το Grid και θέλουμε να βρούμε ποια εγγραφή είναι αυτή. Ανάλογα με το Grid που θα έχεις στην φόρμα θα γράψεις και τον ανάλογο κώδικα για να πάρεις την επιλεγμένη εγγραφή. Π.χ άλλο κώδικα θα θέλει το grid της Microsoft, άλλο της DevExpress, άλλο της C1 κτλ. Με το BindingSource όμως θα μπορούσες απλά να πάρεις την τιμή που έχει το Current property και αναφέρεται στην επιλεγμένη εγγραφή χωρίς να γράψεις κώδικα που να αναφέρεται συγκεκριμένα σε κάποιο Grid. Ο ίδιος κώδικας παίζει ακόμα και αν αύριο αποφασίσεις αντί για Grid να το αλλάξεις σε List ή σε Tree.

    Ας υποθέσουμε τώρα ότι επάνω στην ίδια φόρμα, ή ακόμα και σε διαφορετική αντί για grid έχεις κάποια editors controls όπου εκεί θέλεις να δεις την επιλεγμένη εγγραφή. Δηλαδή το σενάριο είναι επιλέγω μία εγγραφή και θέλω σε μία φόρμα να δω πιο αναλυτικά την εγγραφή αυτή. Με την χρήση του BindingSource αυτό είναι παιχνιδάκι. Αυτό που κάνω είναι να περάσω το BindingSource σαν παράμετρο στην φόρμα αυτή και οι Editors που υπάρχουν θα παίρνουν τις τιμές τους από το Current property του BindingSource. Οπότε ακόμα και αν έχεις τις δύο φόρμες, αυτή του grid και αυτή με τους editors, και αλλάζεις εγγραφή στο grid θα ενημερώνεται αυτόματα και η φόρμα των editors με τις ανάλογες τιμές. Αν τώρα αλλάξεις κάτι στους editors τότε θα αλλάξει και στο grid. Για να μπορέσουν οι editors να πέρνουν την τιμή του current θα πρέπει να κάνεις Bind το property Text ή όποιο άλλο property π.χ για τα CheckBoxes είναι το Checked με το αντίστοιχο πεδίο του DataSource του BindingSource. Οπότε με τον τρόπο αυτό αποφεύγεις να πέρνεις τις τιμές από κάθε ένα control ή και ακόμα να τις βάζεις σε κάθε ένα control. Σίγουρα υπάρχουν αρκετά video στο net για χρήση του BindingSource. Είναι ένα αρκετά εύκολο control το οποίο δίνει μεγάλη ευκολία στον προγραμματιστή.

    Φυσικά τα σενάρια στα οποία θα μπορούσε να χρησιμοποιηθεί το BindingSource πέρα από το παράδειγμα που έγραψα είναι και άλλα, απλά αυτό που ανέφερα είναι αυτό που πας να κάνεις εσύ. Θα έλεγα να το μάθεις asap και θα δεις πόσο θα αλλάξει τον τρόπο που δουλεύεις.

  •  22-05-2010, 13:38 58769 σε απάντηση της 58726

    Απ: Refresh του Grid της Parent form

    Οk, σ' ευχαριστώ θα δοκιμάσω!!Big Smile
  •  27-05-2010, 15:06 58840 σε απάντηση της 58769

    Απ: Refresh του Grid της Parent form

    Ομολογώ πως έχω χαθεί τελείως Stick out tongue. Στην περίπτωση μου δεν ξέρω πως θα το κάνω. Αν μπορείς θα ήθελα να μου πεις πως να προσθέσω μια γραμμή στο gridControl και να φανεί on runtime, την ώρα δηλαδή που πατάω το Save στην φόρμα εισαγωγής εγγραφής. Θα γράψω dataTable.AddRow() και θα το "δει" το bindingSource και κατ' επέκταση το gridControl ή έχει κάποιο property το bindingSource για εισαγωγή γραμμής στη βάση και στο gridControl φυσικά?

    Γράψτο και σε VB.net δεν με πειράζει Smile
  •  27-05-2010, 18:43 58852 σε απάντηση της 58840

    Απ: Refresh του Grid της Parent form

    Συνημμένα: BSDemo.zip

    Σε VB θα το γράψω βέβαια ;)

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

     

  •  31-05-2010, 13:58 58891 σε απάντηση της 58852

    Απ: Refresh του Grid της Parent form

    Ωραία μου δούλεψε μια χαρά! Αν θέλω όμως να έχω Modeless Form, και να γίνεται εισαγωγή εγγραφή χωρίς τη χρήση DialogResult πως θα γίνει; Tongue Tied
  •  01-06-2010, 02:59 58895 σε απάντηση της 58891

    Απ: Refresh του Grid της Parent form

    Στην πρώτη απάντηση που σου έδωσα σου δίνω 3 λύσεις. Διάλεξε αυτή που σου ταιριάζει πιο πολύ. Αν και ένα παράδειγμα με μία model form είναι εύκολο αυτό που ζητάς δεν είναι και τόσο. Όχι γιατί είναι δύσκολο να γίνει απλά πρέπει να λάβουμε υπόψιν και την σχεδίαση της εφαρμογής αλλά και τι θέλουμε να κάνουμε. Παράδειγμα θα ανοίγω νέα φόρμα για κάθε επιλογή του χρήστη στο grid; Αν ναι, τότε αν ο χρήστης διαγράψει μία ανοιχτή εγγραφή τότε λογικά θα πρέπει να κλείσω και την φόρμα που έδειχνε την εγγραφή αυτή. Οπότε κάπου χρειάζομαι να κρατάω μία λίστα με τις εγγραφές και τις φόρμες που έχω ανοίξει.

    Το άλλο σενάριο λέει όχι θέλω να έχω μία φόρμα κάθε φορά ανοιχτή και αν ο χρήστης αλλάξει εγγραφή στο grid τότε να αλλάξουν και τα δεδομένα της φόρμας. Αν όμως έχουν γίνει αλλαγές θα πρέπει να αφήσεις τον χρήστη να πάει σε άλλη εγγραφή χωρίς να τον ρωτήσεις αν θέλει να της αποθηκεύση; Μάλλον όχι αλλά και ναι, εξαρτάται από την εφαρμογή. Οπότε όπως καταλαβαίνεις δεν μπορώ να σου γράψω ένα παράδειγμα.

    Η πιο εύκολη λύση είναι να περάσεις το BindingSource σαν παράμετρο στην φόρμα και να κάνεις τα control bind στο BindingSource. Από εκεί και πέρα υπάρχουν ένα σωρό διαφορετικές σχεδιάσεις και υλοποιήσεις.

    Η ακόμα πιο εύκολη λύση είναι να χρησιμοποιήσεις modal φόρμα και αν σου μείνει χρόνος στο τέλος μέχρι να παραδώσεις ασχολήσου με αυτό.

Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems