1

Access DB テーブルに接続された VB.Net 2008 に DGV があります。DGV は読み取り専用ではありませんが、コンボ ボックスを含む 1 つを除いて読み取り専用の列でいっぱいです。コンボ ボックスを使用すると、ユーザーはその特定の行の結果を選択できます。その後、プログラムは、コンボ ボックスで選択された項目に応じて、事前に計算された値を [利益] 列にコピーします。次に、ユーザーが [保存] ボタンをクリックすると、DB が更新されます (現在は 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 を実行する必要がありますか? そして、私はこれをどこに呼ぶべきですか?

ありがとうございました。

4

5 に答える 5

2

コードをざっと見てみると、次のような疑問が生じます。既存の EventHandler を削除するときに新しい EventHandler を作成した場合、それは同じものですか?

于 2009-02-24T17:22:57.880 に答える
2

同様の問題がありました。CellLeave終了するセルが探しているセル(IE e.ColumnIndex = myEditableColumn.Index)である場合のハンドラーを追加してから、 gv.EndEdit() を呼び出します

また、割り当てと削除のためにハンドラーのメンバー変数を作成することをお勧めします。

于 2009-02-24T17:29:08.223 に答える
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
于 2009-02-24T18:30:42.180 に答える
0

これが古風な投稿であることは承知していますが、この同じ問題を半日悩ませた後、これを別の方法で解決する方法を見つけたので、共有する価値があると思いました.

コンボボックスの leave イベントを処理する 2 番目のハンドラーを追加すると、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
于 2012-06-14T19:20:01.223 に答える
0

CKRet/Quintin さん、素早い回答ありがとうございます。

このコードを簡単に試してみると、コードのブレークポイントとステップ実行がイベントを正しく発生させているようです。私が最後に行った実際の VB プログラミングは VB6 だったので、私は .NET にかなり慣れていないので、これが問題を解決する最もエレガントな方法であるかどうかはわかりません。

また、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
于 2009-02-24T17:57:32.320 に答える