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