Pergunta

Eu tenho um DGV em VB.Net 2008 conectado a uma tabela do Access DB. A DGV não é somente leitura, mas está cheio de colunas somente leitura com exceção de um, que contém uma caixa de combinação. A caixa de combinação permite que o usuário selecione um resultado para essa linha particular, e, em seguida, o programa copia em um valor pré calculado para a coluna "Lucro", dependendo do item selecionado na caixa de combinação. Em seguida, o usuário pressiona o botão Salvar e as atualizações DB (atualmente através de métodos SQL no XSD).

Fácil o suficiente até agora.

Aqui está o código.

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

O problema que tenho é que parece que se um usuário seleciona o resultado desejado na combobox mas NÃO pressione Enter, e simplesmente mouses sobre a uma caixa de combinação diferente para selecione novamente o resultado para uma linha diferente, o primeiro eventhandler não está desligado e, portanto, os eventos disparar várias vezes. Isso, então, faz com que vários erros padrão MsgBox e traz problemas quando o usuário tenta para confirmar todas as alterações ao programa DB / saída etc etc.

O que eu preciso fazer? Preciso .EndEdit algum lugar apropriado para forçar a linha para salvar as alterações? E onde eu deveria chamar isso?

Obrigado.

Foi útil?

Solução

Um rápido olhar sobre o código traz à tona a pergunta: Se você criar um novo EventHandler ao remover o existente é o mesmo?

Outras dicas

Eu tive um problema semelhante, adicione um manipulador para CellLeave se a célula a ser retirado é a célula que você está procurando (IE e.ColumnIndex = myEditableColumn.Index), em seguida, chamar gv.EndEdit ()

Também eu recomendaria fazer as variáveis ??manipuladores membros para atribuição e remoção porque parece mais agradável, em seguida, sempre dizendo remover novo e adicionar novos.

CKRet / Quintin, obrigado pelas respostas rápidas.

A tentativa rápida com este código parece melhor e breakpointing e percorrendo o código parece estar disparando os eventos corretamente. Eu sou bastante novo para .NET como o último VB verdadeira programação que fiz foi VB6, então eu não tenho certeza se esta é a maneira mais elegante para resolver o problema.

Também uma nota que quando LastEventHandler = Nada, chamando a RemoveHandler não lançar uma exceção, que é bastante agradável.

Talvez eu deveria sugerir a MS devem atualizar este artigo.

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

código mais simples que também parece funcionar bem, como sugerido por 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

Eu sei que este é um posto arcaico, mas depois buggering ao redor com esse mesmo problema para metade de um dia eu encontrei uma maneira de resolver isso de outra forma, então eu pensei que seria vale a pena compartilhar.

A adição de um segundo manipulador para manipular o evento licença da caixa de combinação, que, em seguida, remove o manipulador de SelectedValue alterado. Parece funcionar bastante liso, e ao contrário de outra opção que eu encontrei dá a ação resultante desejada (ao contrário de remover o manipulador valor alterado no evento manipulação real que então não a incêndios, se você selecionar novamente a partir do mesmo 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top