Domanda

Ho un DGV in VB.Net 2008 collegato ad una tabella di Access DB. Il DGV non è di sola lettura, ma è pieno di colonne di sola lettura ad eccezione di uno, che contiene una casella combinata. La casella combinata permette all'utente di selezionare un risultato di quella riga particolare, e poi il programma copia di un valore pre calcolata nella colonna "Profit" a seconda della voce selezionata nella casella combinata. Poi l'utente preme il pulsante Salva e gli aggiornamenti DB (attualmente tramite metodi SQL nella XSD).

Facile abbastanza finora.

Ecco il codice.

Private Sub DGUserBets_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DGUserBets.EditingControlShowing

    Dim combo As ComboBox = CType(e.Control, ComboBox)

    If (combo IsNot Nothing) Then

         // Remove an existing event-handler, if present, to avoid 
         // adding multiple handlers when the editing control is reused.
        RemoveHandler combo.SelectedIndexChanged, _
            New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)

        // Add the event handler. 
        AddHandler combo.SelectedIndexChanged, _
            New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)

    End If

End Sub


Private Sub DGUBStake_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

    Dim myStatus As ComboBox = CType(sender, ComboBox)

    Dim row = DGUserBets.CurrentRow

    Select Case myStatus.SelectedIndex
        Case 0
            row.Cells("DGUBProfit").Value = 0
            // pending. no action
        Case 1
            row.Cells("DGUBProfit").Value = row.Cells("DGUBIfWin").Value
            // win
        Case 2
            // loses
            row.Cells("DGUBProfit").Value = row.Cells("DGUBIfLose").Value
        Case 3
            // void
            row.Cells("DGUBProfit").Value = 0
    End Select


End Sub

Il problema che ho è che sembrerebbe che se un utente seleziona il risultato desiderato dalla casella combinata, ma non colpisce Invio, e semplicemente Mouses a una casella combinata diversa per selezionare nuovamente il risultato per una riga diversa, la prima EventHandler non è scollegato e quindi gli eventi fuoco più volte. Questo fa sì che poi i vari errori di default MsgBox e porta in primo piano i problemi quando l'utente tenta di impegnare tutte le modifiche al programma DB / uscita ecc ecc.

Che cosa devo fare? Ho bisogno di un posto .EndEdit opportuno forzare la fila per salvare le modifiche? E dove dovrei chiamare questo?

Grazie.

È stato utile?

Soluzione

Una rapida occhiata al codice di porta in primo piano questa domanda: Se si crea un nuovo EventHandler quando si rimuove quello esistente è lo stesso?

Altri suggerimenti

Ho avuto un problema simile, aggiungere un gestore per CellLeave Se la cella viene uscito è la cella che si sta cercando (IE e.ColumnIndex = myEditableColumn.Index) quindi chiamare gv.EndEdit ()

Anche io consiglierei di effettuare le variabili gestori membri per l'assegnazione e la rimozione perché sembra più bello poi dire sempre Cancella New e aggiungere nuovi.

CKRet / Quintin, grazie per le risposte veloci.

Una prova veloce con questo codice sembra migliore e breakpointing e passando attraverso il codice sembra essere sparando correttamente i fatti. Sono abbastanza nuovo per NET come l'ultima programmazione vera VB ho fatto è stato VB6 quindi non sono sicuro se questo è il modo più elegante per risolvere il problema.

Anche una nota che quando LastEventHandler = Nothing, chiamando il RemoveHandler non un'eccezione, che è molto bella.

Forse dovrei suggerire a MS dovrebbero aggiornare tale articolo.

Private Sub DGUserBets_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DGUserBets.EditingControlShowing

    Dim combo As ComboBox = CType(e.Control, ComboBox)

    Static LastEventHandler As EventHandler

    If (combo IsNot Nothing) Then

        // Remove an existing event-handler, if present, to avoid 
        // adding multiple handlers when the editing control is reused.
        RemoveHandler combo.SelectedIndexChanged, _
            LastEventHandler

        LastEventHandler = New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)

        // Add the event handler. 
        AddHandler combo.SelectedIndexChanged, _
            LastEventHandler

    End If


End Sub

codice più semplice che sembra anche funzionare bene, come suggerito da CKRet:

    Dim combo As ComboBox = CType(e.Control, ComboBox)

    If (combo IsNot Nothing) Then

       RemoveHandler combo.SelectedIndexChanged, AddressOf DGUBStake_SelectedIndexChanged

       AddHandler combo.SelectedIndexChanged, AddressOf DGUBStake_SelectedIndexChanged

    End If

So che questo è un messaggio di arcaico, ma dopo buggering in giro con questo stesso problema per mezza giornata ho trovato un modo per risolvere questo in un altro modo, così ho pensato che sarebbe stato vale la pena condividere.

L'aggiunta di un secondo gestore per gestire l'evento congedo della casella combinata, che quindi rimuove il gestore di SelectedValue cambiato. Sembra funzionare abbastanza liscia, e, a differenza un'altra opzione ho trovato dà l'azione risultante desiderato (a differenza di rimuovere il valore cambiato gestore sull'evento manipolazione reale che poi non si attiva se si ri-select dallo stesso combobox)

Private LastEventHandler As EventHandler = AddressOf Me.ComboBoxValueChanged

Private Sub dgvThisDatagrid_EditingControlShowing(sender As Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvOutstandingReminders.EditingControlShowing

    If TypeOf (e.Control) Is ComboBox Then
        Dim cboThisComboBox = DirectCast(e.Control, ComboBox)

        AddHandler cboThisComboBox.SelectedValueChanged, LastEventHandler

        AddHandler cboThisComboBox.Leave, AddressOf RemoveValueChangedHandler

    End If

End Sub

Private Sub ComboBoxValueChanged(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf (sender) Is ComboBox Then
        Dim cboThisComboBox = DirectCast(sender, ComboBox)

        MessageBox.Show("Value = " & cboThisComboBox.SelectedValue.ToString() & Environment.NewLine & "Text = " & cboThisComboBox.Text) ' Display index
    End If

End Sub

Private Sub RemoveValueChangedHandler(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf (sender) Is ComboBox Then
        Dim cboThisCombobox = DirectCast(sender, ComboBox)

        RemoveHandler cboThisCombobox.SelectedValueChanged, LastEventHandler
    End If

End Sub
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top