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

 

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

Ανανέωση τιμών σε DataGridViewRow ύστερα από SelectedValueChanged σε DropDown ComboBox

Îåêßíçóå áðü ôï ìÝëïò Markos. Τελευταία δημοσίευση από το μέλος Markos στις 28-08-2009, 21:34. Υπάρχουν 0 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  28-08-2009, 21:34 53337

    Ανανέωση τιμών σε DataGridViewRow ύστερα από SelectedValueChanged σε DropDown ComboBox

    Με αφορμή αυτό το thread, ξεκινάω ένα δεύτερο που έχει να κάνει με το πρόβλημα που περιγράφει ο τίτλος. Έγραψα λίγο διερευνητικό κώδικα για να διαπιστώσω κατά πόσο είναι εφικτή η βελτίωση στο user experience. Αποφάσισα να εκμεταλλευτώ το SelectedValueChanged Event του ComboBox προκειμένου να "πιέσω" το datagridview να κάνει τα updates που πρέπει στις τιμές των child cells, αφού επιλεγεί η τιμή από το combo. Δούλεψα κατευθείαν πάνω στο gridview και όχι με τα bindingsources, οπότε φαντάζομαι ότι ο κώδικας επιδέχεται βελτίωση. Έτσι όπως είναι γραμμένος φαίνεται να δουλεύει και εν μέρει με τον τρόπο αυτό προσπαθώ ν' απαντήσω στο τελευταίο ερώτημα του thread του constantine-55. Πρόκειται για επέκταση του κώδικα του solution ανέβασα στο εν λόγω thread, οπότε δεν υπάρχει λόγος να ανεβάσω νέο συνημμένο, παρά μόνο τον κώδικα της φόρμας. Περιμένω τις παρατηρήσεις σας...

    Reminder: I am NOT a VB-er, so be nice...

    Public Class Form1
        Dim generaChildBS As New BindingSource ' Τα bindingsources που θα γίνεται το filtering...
        Dim speciesChildBS As New BindingSource
    
        Private Sub FlowerColourBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FlowerColourBindingNavigatorSaveItem.Click
            Try
                Me.Validate()
                Me.FlowerColourBindingSource.EndEdit()
                Me.TableAdapterManager.UpdateAll(Me.TaxonomyDataSet)
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
    
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.FamiliesTableAdapter.Fill(Me.TaxonomyDataSet.Families)
            Me.GeneraTableAdapter.Fill(Me.TaxonomyDataSet.Genera)
            Me.SpeciesTableAdapter.Fill(Me.TaxonomyDataSet.Species)
            Me.FlowerColourTableAdapter.Fill(Me.TaxonomyDataSet.FlowerColour)
            '
            generaChildBS.DataSource = Me.TaxonomyDataSet
            generaChildBS.DataMember = "Genera"
            '
            speciesChildBS.DataSource = Me.TaxonomyDataSet
            speciesChildBS.DataMember = "Species"
        End Sub
    
        Private Sub FlowerColourDataGridView_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles FlowerColourDataGridView.EditingControlShowing
            If Me.FlowerColourDataGridView.CurrentCell.ColumnIndex = FamilyCombo.Index Then
                Dim control = CType(e.Control, DataGridViewComboBoxEditingControl)
                AddHandler control.SelectedValueChanged, AddressOf FamilyCombo_SelectedValueChanged
            ElseIf Me.FlowerColourDataGridView.CurrentCell.ColumnIndex = GenusCombo.Index Then
                Dim control = CType(e.Control, DataGridViewComboBoxEditingControl)
                control.DataSource = Me.generaChildBS
                '
                Me.FilterGeneraChildBindingSource()
                '
                ' Όταν εμφανιστεί το combo, και στο κελί υπάρχει ήδη τιμή, πρέπει η επιλεγμένη τιμή στο combo
                ' να είναι ίδια με εκείνη του κελιού
                If Not String.IsNullOrEmpty(Me.FlowerColourDataGridView.CurrentCell.Value.ToString()) Then
                    control.SelectedValue = Me.FlowerColourDataGridView.CurrentCell.Value
                End If
                '
                AddHandler control.SelectedValueChanged, AddressOf GenusCombo_SelectedValueChanged ' Ο event handler πρέπει να προστεθεί ύστερα από το SelectedValue "assignement"
            ElseIf Me.FlowerColourDataGridView.CurrentCell.ColumnIndex = SpeciesCombo.Index Then
                Dim control = CType(e.Control, DataGridViewComboBoxEditingControl)
                control.DataSource = Me.speciesChildBS
                '
                Me.FilterSpeciesChildBindingSource()
                '
                If Not String.IsNullOrEmpty(Me.FlowerColourDataGridView.CurrentCell.Value.ToString()) Then
                    control.SelectedValue = Me.FlowerColourDataGridView.CurrentCell.Value
                End If
                '
                AddHandler control.SelectedValueChanged, AddressOf SpeciesCombo_SelectedValueChanged ' Ο event handler πρέπει να προστεθεί ύστερα από το SelectedValue "assignement"
            End If
        End Sub
    
        Private Sub FamilyCombo_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim control = CType(sender, DataGridViewComboBoxEditingControl)
            Dim dgv = CType(control.Parent.Parent, DataGridView)
            '
            Dim currentFamilyValue = CType(Me.FlowerColourBindingSource.Current, DataRowView)("Family").ToString()
            If control.SelectedValue IsNot Nothing Then
                Dim selectedFamilyValue = control.SelectedValue.ToString()
                If (currentFamilyValue <> selectedFamilyValue) Then
                    Me.FlowerColourDataGridView.CurrentCell.Value = selectedFamilyValue
                End If
            End If
            '
            RemoveHandler control.SelectedValueChanged, AddressOf FamilyCombo_SelectedValueChanged
        End Sub
    
        Private Sub GenusCombo_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim control = CType(sender, DataGridViewComboBoxEditingControl)
            Dim dgv = CType(control.Parent.Parent, DataGridView)
            '
            Dim currentGenusValue = CType(Me.FlowerColourBindingSource.Current, DataRowView)("Genus").ToString()
            If control.SelectedValue IsNot Nothing Then
                Dim selectedGenusValue = control.SelectedValue.ToString()
                If (currentGenusValue <> selectedGenusValue) Then
                    Me.FlowerColourDataGridView.CurrentCell.Value = selectedGenusValue
                End If
            End If
            '
            RemoveHandler control.SelectedValueChanged, AddressOf GenusCombo_SelectedValueChanged
        End Sub
    
        Private Sub SpeciesCombo_SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim control = CType(sender, DataGridViewComboBoxEditingControl)
            Dim dgv = CType(control.Parent.Parent, DataGridView)
            '
            Dim currentSpeciesValue = CType(Me.FlowerColourBindingSource.Current, DataRowView)("Species").ToString()
            If control.SelectedValue IsNot Nothing Then
                Dim selectedSpeciesValue = control.SelectedValue.ToString()
                If (currentSpeciesValue <> selectedSpeciesValue) Then
                    Me.FlowerColourDataGridView.CurrentCell.Value = selectedSpeciesValue
                End If
            End If
            '
            RemoveHandler control.SelectedValueChanged, AddressOf SpeciesCombo_SelectedValueChanged
        End Sub
    
        Private Sub FilterGeneraChildBindingSource()
            'Dim familyName = Me.FlowerColourDataGridView.Rows(Me.FlowerColourDataGridView.CurrentCell.RowIndex).Cells(FamilyCombo.Index).Value.ToString()
            '
            Dim familyName = CType(Me.FlowerColourBindingSource.Current, DataRowView)("Family").ToString()
            If Not String.IsNullOrEmpty(familyName) Then
                Dim familyRow = CType(Me.FamiliesBindingSource.Item(Me.FamiliesBindingSource.Find("FamilyName", familyName)), DataRowView)
                Dim familyID = CType(familyRow("FamilyID"), Short)
                generaChildBS.Filter = "FamilyID=" + familyID.ToString()
            Else
                generaChildBS.Filter = "FamilyID=-1" ' Εάν δεν έχει επιλεγεί οικογένεια, τότε η λίστα των γενών πρέπει να είναι κενή
            End If
        End Sub
    
        Private Sub FilterSpeciesChildBindingSource()
            'Dim genusName = Me.FlowerColourDataGridView.Rows(Me.FlowerColourDataGridView.CurrentCell.RowIndex).Cells(GenusCombo.Index).Value.ToString()
            '
            Dim genusName = CType(Me.FlowerColourBindingSource.Current, DataRowView)("Genus").ToString()
            If Not String.IsNullOrEmpty(genusName) Then
                speciesChildBS.Filter = "Genus='" + genusName + "'"
            Else
                speciesChildBS.Filter = "Genus=''" ' Εάν δεν έχει επιλεγεί γένος, τότε η λίστα των ειδών πρέπει να είναι κενή
            End If
        End Sub
    
        Private Sub FlowerColourDataGridView_DataError(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles FlowerColourDataGridView.DataError
            MessageBox.Show(e.Exception.Message)
            e.Cancel = True
        End Sub
    
    
        Private Sub FlowerColourDataGridView_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles FlowerColourDataGridView.CellValueChanged
            '
            ' Όπως σου είπα πιο πάνω, πιο σωστό όπου μπορείς να επεμβαίνεις κατευθείαν στο bindingsource και
            ' όχι στο grid. Για το λόγο αυτό, δοκίμασε να "παίξεις" με το "CurrentItemChanged" event του FlowerColourBindingSource,
            ' αντί του "CellValueChanged" event του FlowerColourDataGridView...
            '
            If e.RowIndex <> Me.FlowerColourDataGridView.NewRowIndex Then
                If e.ColumnIndex = FamilyCombo.Index Then
                    Me.FlowerColourDataGridView.Rows(e.RowIndex).Cells(Me.GenusCombo.Index).Value = DBNull.Value
                ElseIf e.ColumnIndex = GenusCombo.Index Then
                    Me.FlowerColourDataGridView.Rows(e.RowIndex).Cells(Me.SpeciesCombo.Index).Value = DBNull.Value
                ElseIf e.ColumnIndex = SpeciesCombo.Index Then
                    Me.FlowerColourDataGridView.Rows(e.RowIndex).Cells(Me.FlowerColourTextBox.Index).Value = DBNull.Value
                End If
                '
                ' Στο παρόν παράδειγμα έκανα τις στήλες του DataTable Nullable. Αν δεν είναι και στη βάση, τότε
                ' είναι σχεδόν βέβαιο ότι θα φας exception. Οπότε πιο λογικό είναι κάθε φορά που αλλάζει η
                ' τιμή ενός κελιού σε μεγαλύτερο επίπεδο, τα μικρότερα να παίρνουν μια default τιμή...
                '
                'If e.ColumnIndex = FamilyCombo.Index Then
                '    Me.FilterGeneraChildBindingSource()
                '    Me.FlowerColourDataGridView.Rows(e.RowIndex).Cells(Me.GenusCombo.Index).Value = CType(Me.generaChildBS(0), DataRowView)("Genus").ToString()
                'ElseIf e.ColumnIndex = GenusCombo.Index Then
                '    Me.FilterSpeciesChildBindingSource()
                '    Me.FlowerColourDataGridView.Rows(e.RowIndex).Cells(Me.SpeciesCombo.Index).Value = CType(Me.speciesChildBS(0), DataRowView)("Species").ToString()
                'ElseIf e.ColumnIndex = SpeciesCombo.Index Then
                '    Me.FlowerColourDataGridView.Rows(e.RowIndex).Cells(Me.FlowerColourTextBox.Index).Value = "New colour"
                'End If
            End If
        End Sub
    
        Private Sub btnReloadData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReloadData.Click
            Me.FlowerColourTableAdapter.Fill(Me.TaxonomyDataSet.FlowerColour)
        End Sub
    End Class

     


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