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

 

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

Υπολογισμός unbound columns ανά row σε databound datagridview (rowadded / cellformatting events)

Îåêßíçóå áðü ôï ìÝëïò cap. Τελευταία δημοσίευση από το μέλος KelMan στις 30-06-2007, 20:29. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  29-06-2007, 02:41 33271

    Υπολογισμός unbound columns ανά row σε databound datagridview (rowadded / cellformatting events)

    Το σενάριο είναι απλό: Εχω ένα databound datagridview στο οποίο θέλω να προσθέσω ένα unbound column το οποίο να υπολογίζει την τιμή του βάσει κάποιων άλλων τιμών του τρέχοντος row. Συνεπώς όταν ξεκινάει το datagridview να φέρνει τα rows του, θέλω να γίνεται ο υπολογισμός για κάθε row. Αμ δε!

    EDIT: Για να είναι πιό πλήρης η περιγραφή να πω οτι κάνω declarative και όχι programmatic databinding.

    Δοκίμασα να αξιοποιήσω το RowsAdded event, αλλά έχει την εξής περίεργη συμπεριφορά (παρά τα όσα χαρούμενα λέει το documentation για αυτό): Γινεται raise ΔΥΟ ΜΟΝΟ φορές, όσα rows και να έχω, και μάλιστα ο κώδικας που έχω γράψει εντός του event φαίνεται να τρέχει κανονικά και να υπολογίζει τιμές ΜΟΝΟ ΓΙΑ ΤΑ ΔΥΟ ΠΡΩΤΑ rows του datagridview μου! Μετά τίποτα! Ακόμα και με debug/step είδα οτι μετά τη δεύτερη φορά που γίνεται raise το event, "σκάνε" επάνω στο datagrid όλα τα rows χωρίς να ξανατρέξει το άτιμο. (Δεν είμαι τρελλός! Και αυτός εδώ ο άμοιρος το έχει διαπιστώσει: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1586558&SiteID=1)

    Δοκίμασα επίσης το CellFormatting event ως το μόνο εναλλακτικό που είχα στη διάθεσή μου. Δυστυχώς όμως αυτό τρέχει όχι μόνο όταν φτιάχνεται το datagridview, αλλά και όταν αλλάξω κελί, αλλάξω row, κουνήσω τον κέρσορα, βήξω, φταρνιστώ, κάνει δηλώσεις ο κυβερνητικός εκπρόσωπος ή κορνάρει ένα αυτοκίνητο από το δρόμο. Οπως καταλαβαίνετε, μάλλον είναι ασύμφορο μια και η τιμή του unbound column απαιτεί χρόνο και resources για να υπολογιστεί.

    Τι άλλο θα μπορούσα να δοκιμάσω; Να τραβήξω καμμια αγωγή στο RowsAdded event για παραπλάνηση κοινού;

     


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
    Δημοσίευση στην κατηγορία: , , ,
  •  29-06-2007, 08:41 33274 σε απάντηση της 33271

    Απ: Υπολογισμός unbound columns ανά row σε databound datagridview (rowadded / cellformatting events)

    Σωτήρη, αν και μου κάνει εντύπωση το γιατί δεν παίξει το unbound column out-of-the-box, δοκίμασε να παίξεις ένα level παραπίσω. Αν έχεις ως datasource ένα DataTable, άλλαξε το DataSet και πρόσθεσε ένα computed column. Άν έχεις κάποιo object, βάλε ένα νέο property. Έτσι, ο designer θα το δει κατευθείαν. Επίσης, δοκίμασε να εκμεταλλευτείς τα events του DataBindingSource.


    Vir prudens non contra ventum mingit
  •  29-06-2007, 13:48 33279 σε απάντηση της 33274

    Απ: Υπολογισμός unbound columns ανά row σε databound datagridview (rowadded / cellformatting events)

    Κάνοντας declarative την όλη ιστορία αναπόφευκτα έχω ένα bindingsource ως datasource στο datagridview.

    Δεν κατάλαβα τη φράση σου με το out-of-the-box για να είμαι ειλικρινής. Το unbound column προστίθεται κανονικά. Οταν όμως πάω να το γεμίσω προγραμματιστικά θα πρέπει να "κολλήσω" τον κώδικα που το γεμίζει για κάθε row σε κάποιο event. Εχω τα δύο events που προανέφερα, με ενδεδειγμένο για την περίπτωσή μου το RowsAdded, όμως φαίνεται να μην λειτουργεί σωστά (να μην γίνεται raise για κάθε row, όπως προανέφερα).

    Υπάρχει event στο bindingsource το οποίο να τρέχει ανά row όταν γίνεται αυτό bind σε datagridview; Αν ναι, πώς θα μπορούσα όμως να πειράξω το unbound column, μια και φαντάζομαι οτι αυτό το event (αν υπάρχει) θα τρέχει ΠΡΙΝ προστεθεί νέο row στο datagridview;


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  29-06-2007, 15:27 33280 σε απάντηση της 33279

    Απ: Υπολογισμός unbound columns ανά row σε databound datagridview (rowadded / cellformatting events)

    Μετά από λίγη έρευνα, κοιτάξτε το κουλό που συμβαίνει στο RowsAdded Event:

    Σύμφωνα με το βιβλιαράκι "Databinding With Windows Forms 2.0" οπου βρήκα ένα απόσπασμα ισχύει το εξής: The RowsAdded event can be fired for one row at a time if you are programmatically adding rows in a loop, or it can be fired just once for a whole batch of rows being added, such as when you data bind or use the AddCopies method of the rows collection.

    Οκ, αρα λοιπόν βρήκαμε οτι όταν κάνουμε databinding το RowsAdded event έχει διαφορετική συμπεριφορά. @%@$%@#$. Για να δούμε όμως, ισχύει τελικά αυτό; Εβαλα το εξής στο RowsAdded Event για να δούμε τι θα γίνει:

    Private Sub DataGridView1_RowsAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) Handles DataGridView1.RowsAdded

    MsgBox("rowindex:" + e.RowIndex.ToString + " rowcount:" + e.RowCount.ToString)

    Next
    End Sub

    Με την εκτέλεση φαίνεται ξεκάθαρα οτι το event τρέχει ΔΥΟ φορές και μόνο δυο. Τα αποτελέσματα είναι τα εξής (έχω 570 γραμμές που θα μπουν στο datagridview):

    rowindex:0 rowcount:1
    rowindex:1 rowcount:570

    ΕΛΕΟΣ κύριοι που σχεδιάσατε το datagridview! Διαφορετική συμπεριφορά στο programmatic binding, διαφορετική στο declarative, και τρέχει και ΔΥΟ φορές το event; Τελος πάντων, μπορώ τώρα να δέσω τα unbound columns μου στο event αυτό με ένα loop ως εξής:

    For Each r As DataGridViewRow In DataGridView1.Rows

    ' ...εδώ ο καλός ο κώδικας που δένει τα unbound

    Next

    Και βέβαια, FYI και FMI, μπορεί να χρησιμοποιηθεί και το CellFormatting Event, το οποίο όμως έχει την κακή διάθεση να τρέχει συνεχώς. Ακόμα και αν το περιορισουμε κοιτώντας το Index του column, και πάλι δεν μπορούμε να αποφύγουμε το οτι τρέχει οταν ο δρομέας μας περνάει απλώς πάνω από ένα κελί...

    Χαρακτηρίζω το θέμα ως επιλυθέν θεωρώντας οτι το αρχικό πρόβλημα λύθηκε. Παρ'όλα αυτά, θα ήθελα να ακούσω απόψεις για την περίεργη αυτή συμπεριφορά του RowsAdded event.

     

     


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
    Δημοσίευση στην κατηγορία: , , ,
  •  30-06-2007, 20:29 33295 σε απάντηση της 33280

    Απ: Υπολογισμός unbound columns ανά row σε databound datagridview (rowadded / cellformatting events)

    Με το δίκιο σου δεν κατάλαβες το “out-of-the-box”, δικό μου λάθος, μπερδεύτικα με το computed column του DataTable όπου μπορείς να ορίσεις formula.

    Λοιπόν, αν και επιμένω στο ότι σωστότερο είναι το extra column να μπει εκ των προτέρων ως computed column στο DataTable ή ως property σε DataSource object, τελικά βρήκα μια λύση για να παίξεις πάνω στο DataGridView. Το κόλπο είναι να βάλεις τον DataGridView σε Virtual Mode.

    To Virtual Mode σε υποχρεώνει να χειρίζεται εσύ το πότε θα περάσεις data από το source στο DGV και πίσω. Στην περίπτωσή, μιας και έχεις data binding δεν χρειάζεται να ασχοληθείς με τα data που έχεις ήδη αλλά μόνο με τα data που δεν έχεις, ήτοι το computed column.

    Αν και τα λέει όλα αρκετά αναλυτικά στο MSDN, σου παραθέτω τον κώδικα που δοκίμασα ότι παίζει το concept. Χρειάζεσαι μια φόρμα και ένα data source που στην συγκεκριμένη περίπτωση είναι ο πίνακας Products . Κάνεις το κλασικό data binding και κατόπιν προσθέτεις ένα unbound column. Εδώ, έχω ένα computed column που είναι το γινόμενο UnitPrice * UnitsInStoc. To unbound column έχει index 7.

    Οι τιμές που θέλεις να εμφανίζονται στο unbound column αποθηκεύονται σε ένα Generic Dictionary και μέσα από τα τρία παρακάτω events τις διαβάζεις και τις γράφεις όταν χρειάζεται.

        Private computedValuesStore As System.Collections.Generic.Dictionary(Of Integer, Decimal)

     

        Private Sub ProductsDataGridView_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles ProductsDataGridView.CellValueChanged

            If e.RowIndex <> -1 AndAlso e.ColumnIndex = 7 Then

                Dim productID As Integer = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("ProductID").Value, Integer)

                Dim unitPrice As Decimal = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("DataGridViewTextBoxColumn6").Value, Decimal)

                Dim unitsInStoc As Decimal = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("DataGridViewTextBoxColumn7").Value, Decimal)

                computedValuesStore(productID) = unitPrice * unitsInStoc

            End If

        End Sub

     

        Private Sub ProductsDataGridView_CellValueNeeded(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellValueEventArgs) Handles ProductsDataGridView.CellValueNeeded

            If e.ColumnIndex = 7 Then

                Dim productID As Integer = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("ProductID").Value, Integer)

                If computedValuesStore.ContainsKey(productID) Then

                    e.Value = computedValuesStore(productID)

                Else

                    Dim unitPrice As Decimal = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("DataGridViewTextBoxColumn6").Value, Decimal)

                    Dim unitsInStoc As Decimal = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("DataGridViewTextBoxColumn7").Value, Decimal)

                    e.Value = unitPrice * unitsInStoc

                End If

            End If

        End Sub

     

        Private Sub ProductsDataGridView_CellValuePushed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellValueEventArgs) Handles ProductsDataGridView.CellValuePushed

            If e.ColumnIndex = 7 Then

                Dim productID As Integer = CType(ProductsDataGridView.Rows(e.RowIndex).Cells("ProductID").Value, Integer)

                If Not computedValuesStore.ContainsKey(productID) Then

                    computedValuesStore.Add(productID, CType(e.Value, Decimal))

                Else

                    computedValuesStore(productID) = CType(e.Value, Decimal)

                End If

            End If

        End Sub


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