我在VB.Net 2008中有一个连接到Access数据库表的DGV。 DGV不是只读的,但除了包含组合框的列之外,其中包含只读列。组合框允许用户选择该特定行的结果,然后程序将预先计算的值复制到“利润”列中,具体取决于组合框中选择的项目。然后用户点击“保存”按钮并更新数据库(目前通过XSD中的SQL方法)。
到目前为止还很容易。
这是代码。
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
我遇到的问题是,如果用户从组合框中选择了所需的结果但是没有按Enter键,只需将鼠标移到另一个组合框上再次选择不同行的结果,第一个事件处理程序未断开连接,因此事件多次触发。这会导致各种默认的MsgBox错误,并在用户尝试提交对DB / exit程序等的所有更改时出现问题。
我需要做什么?我是否需要.EndEdit适当的地方强制行保存更改?我应该在哪里打个电话?
谢谢。
答案 0 :(得分:2)
快速浏览代码会提出这个问题: 如果在删除现有的EventHandler时创建一个新的EventHandler它是同一个吗?
答案 1 :(得分:2)
我遇到了类似的问题,如果退出的单元格是您要查找的单元格(IE CellLeave
),则为e.ColumnIndex = myEditableColumn.Index
添加处理程序,然后调用gv.EndEdit()
此外,我建议将处理程序成员变量用于赋值和删除,因为它似乎更好,然后总是说删除新建和添加新。
答案 2 :(得分:0)
CKRet / Quintin,谢谢您的快速回复。
使用此代码进行快速尝试似乎更好,并且通过代码的断点和步进似乎正在正确地触发事件。我是.NET的新手,因为我做的最后一个真正的VB编程是VB6所以我不确定这是否是解决问题的最优雅的方法。
另请注意,当LastEventHandler = Nothing时,调用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
答案 3 :(得分: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
答案 4 :(得分:0)
我知道这是一个古老的帖子,但是在经历了半天的同样问题之后,我找到了另一种解决方法,所以我认为值得分享。
添加第二个处理程序来处理组合框的leave事件,然后删除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