更改 datagridview 选定的行不会自动清除任何文本框或任何其他表单控件,除非您将事件处理程序分配给清除数据的 datagridview 的“.SelectionChanged”事件。
诀窍是在清除表单数据或采取任何其他操作之前,您必须检查所选行索引的有效性。如果表单控件中的数据已被修改,并且您希望将修改后的数据保留在表单控件中,则必须阻止调用清除表单数据的过程。
我有下面的完整代码。这是可靠、稳定的,我想是最简单的方法。创建一个Form,然后创建一个名为“DGVobj”的datagridview对象和一个名为“Button1”的按钮来测试代码。“Button1”切换布尔值以允许或不允许更改所选行。
“TakeAction()”过程仅且仅在函数“CheckIfDataHasChanged()”返回 false 时执行。换言之,“TakeAction()”只有在表单数据没有改变的情况下才会被执行。如果表单数据改变,则执行“SelectThePreviousRow()”过程。此过程清除用户选择的行的选择,并再次选择前一行。有效行的索引存储在变量“PrvRowIdx”中。如果您不想让用户更改行选择,则需要“PrvRowIdx”。
您需要过程“DGV_CellBeginEdit()”来处理 datagridview 的“CellBeginEdit”事件。如果数据发生更改,并且用户将编辑的单元格的行索引与用户已编辑数据的行的索引不同,您不希望允许用户编辑新行.
您会看到我没有使用“.RowValidating”事件及其事件取消方法。因为“.RowValidating”事件在“.SelectionChanged”事件之前触发,您将没有机会检查用户是否选择了新行。
布尔变量“bln_clearingSelection”、“bln_CancelingEdit”和“bln_RowSelectionIsChanging”用于防止多次调用过程并防止“StackOverFlow”异常。如果用户坚持通过不停地单击行和单元格来更改所选行,这可以防止“StackOverFlow”异常被触发。
“DataGridViewTestForm”是一个表单对象。
Public Class DataGridViewTestForm
Private WithEvents DGVobj3 As New System.Windows.Forms.DataGridView
Private dgvSelectedRow As System.Windows.Forms.DataGridViewRow
Dim PrvRowIdx As Integer = -1
Private bln_AllowRowChange As Boolean = False
Private bln_clearingSelection As Boolean = False, bln_CancelingEdit As Boolean = False, bln_RowSelectionIsChanging As Boolean = False
Public Sub New()
' This call is required by the designer.
InitializeComponent()
DGVobj.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect
DGVobj.MultiSelect = False
Button1.Text = "Not Allowed"
CreateNewDataTable()
End Sub
Private Sub CreateNewDataTable()
Dim objTable As New System.Data.DataTable
Dim col1 As New System.Data.DataColumn("Column1")
Dim col2 As New System.Data.DataColumn("Column2")
objTable.Columns.Add(col1)
objTable.Columns.Add(col2)
Dim rw1 As System.Data.DataRow = objTable.NewRow
Dim rw2 As System.Data.DataRow = objTable.NewRow
Dim rw3 As System.Data.DataRow = objTable.NewRow
objTable.Rows.Add(rw1)
objTable.Rows.Add(rw2)
objTable.Rows.Add(rw3)
DGVobj.DataSource = objTable
End Sub
Private Sub DGV_SelectionChanged(sender As DataGridView, e As EventArgs) Handles DGVobj.SelectionChanged
If (bln_clearingSelection Or bln_CancelingEdit Or bln_RowSelectionIsChanging) Then
Exit Sub
End If
If CheckIfDataHasChanged() Then
SelectThePreviousRow()
Else
TakeAction()
End If
End Sub
Private Sub TakeAction()
bln_RowSelectionIsChanging = True
Dim dgvSRows As DataGridViewSelectedRowCollection = DGVobj.SelectedRows
If dgvSRows IsNot Nothing Then
If dgvSRows.Count = 1 Then
dgvSelectedRow = dgvSRows.Item(0)
PrvRowIdx = dgvSelectedRow.Index
End If
End If
ClearFormControls()
bln_RowSelectionIsChanging = False
End Sub
Private Sub ClearFormControls()
End Sub
Private Function SelectThePreviousRow() As Boolean
bln_clearingSelection = True
Dim bln_Reverted As Boolean = False
Dim dgvRowCollection As DataGridViewSelectedRowCollection = DGVobj.SelectedRows
If dgvRowCollection IsNot Nothing Then
DGVobj.ClearSelection()
bln_Reverted = True
End If
If PrvRowIdx >= 0 Then
If DGVobj.Rows IsNot Nothing Then
DGVobj.Rows.Item(PrvRowIdx).Selected = True
End If
End If
bln_clearingSelection = False
Return bln_Reverted
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If bln_AllowRowChange Then
bln_AllowRowChange = False
Button1.Text = "Not Allowed"
Else
bln_AllowRowChange = True
Button1.Text = "Allowed"
End If
End Sub
Private Sub DGV_CellBeginEdit(sender As DataGridView, e As DataGridViewCellCancelEventArgs) Handles DGVobj.CellBeginEdit
Dim bln_CancelingEdit = True
Dim bln_EditWasCanceled As Boolean = False
Dim RowIdx As Integer = e.RowIndex
Dim dgvRowCollection As DataGridViewSelectedRowCollection = DGVobj.SelectedRows
If dgvRowCollection IsNot Nothing Then
Dim rwCnt As Integer = dgvRowCollection.Count
If rwCnt = 1 Then
If PrvRowIdx <> RowIdx Then
e.Cancel = True
bln_EditWasCanceled = True
End If
Else
e.Cancel = True
bln_EditWasCanceled = True
End If
Else
e.Cancel = True
bln_EditWasCanceled = True
End If
bln_CancelingEdit = False
End Sub
Private Function CheckIfDataHasChanged() As Boolean
If bln_AllowRowChange Then
Return False
Else
Return True
End If
End Function
End Class