1

我在连接到Access数据库表的VB.Net 2008中有一个DGV。 DGV不是只读的,但除了包含组合框的一列外,其中只有只读列。组合框允许用户选择该特定行的结果,然后该程序根据在组合框中选择的项目将预先计算的值复制到“利润”列中。然后用户点击保存按钮并更新数据库(目前通过XSD中的SQL方法)。EditingControlShowing事件触发多次

到目前为止还不够容易。

这是代码。

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 

我的问题是,它似乎是,如果用户选择从ComboBox所期望的结果,但不敲回车,并简单地将鼠标到一个不同的组合框,再次选择不同行的结果,第一个事件处理程序不会断开连接,因此事件会多次触发。然后,这会导致各种默认MSGBOX错误,并提出了问题,当用户试图提交到DB /出口程序等等等等

什么我需要做的所有更改?我是否需要.EndEdit适当的地方强制行以保存更改?我应该在哪里调用?

谢谢。

回答

2

快速浏览代码引发了这个问题: 如果您在删除现有的EventHandler时创建了一个新的EventHandler,它是相同的吗?

+0

嗯.. EditControlShowing代码来自MSDN。你认为我可能没有正确实施它吗? http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxitingitingcontrol.aspx – user57087 2009-02-24 17:28:41

+0

当您使用AddHandler时,您不会将创建的EventHandler保存在任何地方。做到这一点,并在调用RemoveHandler时使用该引用。 – 2009-02-24 17:37:17

+0

在另一方面:你不应该甚至需要使用新EvenHandler: RemoveHandler combo.SelectedIndexChanged,AddressOf DGUBStake_SelectedIndexChanged 的AddHandler combo.SelectedIndexChanged,AddressOf DGUBStake_SelectedIndexChanged 应该做的。 – 2009-02-24 17:46:58

2

我也有过类似的问题,添加一个处理CellLeave如果要退出的细胞就是你正在寻找的小区(即e.ColumnIndex = myEditableColumn.Index)然后调用gv.EndEdit()

此外,我会建议做处理程序成员变量的分配和删除,因为它看起来更好,然后总是说删除新增和添加新。

0

CKRet/Quintin的,谢谢你的快速响应。

快速尝试用这个代码看起来更好,设置断点并逐步执行代码似乎是正确的射击事件。我对.NET相当陌生,因为我所做的最后一个真正的VB编程是VB6,所以我不确定这是否是解决问题最优雅的方法。

也是一个需要注意的是,当LastEventHandler =没什么,调用RemoveHandler不抛出一个异常,这是相当不错的。

也许我应该建议MS应该更新的文章。

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 
0

这似乎也工作得很好,如建议通过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 
0

我知道这是一个古老的职位,但与此相同的问题围绕buggering半天我后我找到了另一种解决方法,所以我认为这是值得分享的。

添加第二个处理器来处理组合框,然后删除的SelectedValue的改变了处理器的假事件。看起来工作非常光滑,而且与我发现的另一个选项不同,它提供了期望的结果操作(不同于在实际操作事件中移除值更改的处理程序,如果您从同一个组合框重新选择,则不会触发)

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