datagridview 更新后继续关注行
Keep focus on row after datagridview update
我正在创建一个 VB windows 应用程序。该应用程序的重点是一个简单的 DataGridView
,我从 SQL 服务器数据库中获取 View
。
DataGridView
每秒刷新一次,所以我可以在我的 GridView 中看到新的数据收入。
问题是在刷新后继续关注行。我需要解决方案,在我点击一行或一个单元格后,即使在刷新后它也会让我保持在上面。
这是我的代码:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Refresh every 1 sec
Dim timer As New Timer()
timer.Interval = 1000
AddHandler timer.Tick, AddressOf timer_Tick
timer.Start()
'TODO: This line of code loads data into the 'XYZDataSet.view1' table. You can move, or remove it, as needed.
Me.View1TableAdapter.Fill(Me.XYZDataSet.view1)
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
Private Sub DataGridView1_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
If Me.DataGridView1.Rows(i).Cells("DayTillDelivery").Value <= 30 Then
Me.DataGridView1.Rows(i).Cells("DayTillDelivery").Style.ForeColor = Color.Red
End If
Next
End Sub
Private Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
'Calling refresh after 1 second and updating the data
Me.DataGridView1.Refresh()
Me.View1TableAdapter.Fill(Me.XYZDataSet.view1)
End Sub
End Class
我过去解决了类似的问题,方法是在刷新之前将 selected 单元格的索引存储在一个变量中,因此我能够恢复 selection通过在更新后调用 DataGridView.Rows(selRow).Cells(selCol).Selected = True
。
编辑 - 示例代码:
To later readers:
Please take a look at Edit#2 where I describe a better method to re-select the previous selected cell!
示例代码:
' Variables for remembering the indexes of the selected cell
Dim selRow As Integer
Dim selCol As Integer
' Check if there is a selected cell to prevent NullPointerException
If DataGridView1.SelectedCells().Count > 0 Then
selRow = DataGridView1.CurrentCell.RowIndex
selCol = DataGridView1.CurrentCell.ColumnIndex
End If
' Dummy "update"
' don't forget to clear any existing rows before adding the new bunch (only if you always reloading all rows)!
DataGridView1.Rows.Clear()
For index = 1 To 20
DataGridView1.Rows.Add()
Next
' Check if there are "enough" rows after the update,
' to prevent setting the selection to an rowindex greater than the Rows.Count - 1 which would
' cause an IndexOutOfBoundsException
If (DataGridView1.Rows.Count - 1) > selRow Then
' Clear selection and then reselect the cell that was selected before by index
DataGridView1.ClearSelection()
' For the next line of code, there is a better solution in Edit #2!
DataGridView1.Rows(selRow).Cells(selCol).Selected = True
End If
请注意:
- 此过程要求您按照更新前添加行的顺序添加行,因为只有 selected 行的
.Index
存储在变量中。如果您以不同的顺序读取行,那么刷新后 select 将 select 编辑 相同位置 的行。
- 您应该添加检查是否有 selected 行(以防止
NullPointerException
)以及 DataGridView
[=49] 中是否有“足够”的行=]在刷新后,防止出现IndexOutOfBoundsException
.
- 这仅在
DataGridView1.SelectionMode
指向实际 select 行的内容时有效,例如 FullRowSelect
。
- 在通过更新添加新行之前,不要忘记清除任何现有行(仅当您始终重新加载所有行时)。
编辑 2 - RowHeader 三角形和意外的 MultiSelect
如以下评论所述,如果用户按住鼠标按钮超过刷新周期,会出现一种奇怪的行为,会导致意外的多选。此外,RowHeader 三角形未设置为正确的行。
经过一番研究,我找到了解决此问题的方法。不要将给定单元格的 .Selected
-属性 设置为 True
,而是将 DataGridView
的 .CurrentCell
-属性 设置为您要设置的单元格想select!
在代码中,这意味着改变
DataGridView1.Rows(selRow).Cells(selCol).Selected = True
到
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol)
好了。 :-)
在填充之前,存储 CurrentRow 值和 currenCell 列:
Dim currentColumnIndex As Integer = 0 ;
Dim currentValues As List(Of Object) = If(DataGridView1.CurrentRow Is Nothing, Nothing, New List(Of Object)())
If currentValues IsNot Nothing Then
For i As Integer = 0 To DataGridView1.Columns.Count - 1
currentValues.Add(DataGridView1.CurrentRow.Cells(i).Value)
Next
currentColumnIndex = DataGridView1.CurrentCell.ColumnIndex;
End If
Fill后,搜索存储值对应的行:
Dim i As Integer = 0
While i < DataGridView1.Rows.Count AndAlso currentValues IsNot Nothing
Dim areIdentical As Boolean = True
Dim j As Integer = 0
While j < DataGridView1.Columns.Count AndAlso areIdentical
areIdentical = DataGridView1.Rows(i).Cells(j).Value = currentValues(j)
j += 1
End While
If areIdentical Then
DataGridView1.CurrentCell = DataGridView1.Rows(i).Cells(currentColumnIndex)
currentValues = Nothing
End If
i += 1
End While
注意:"For/While" 循环编码可能不是最佳的,因为它是从 C# 自动转换为 vb.net 的结果。
C# 修复代码,下一个重新加载模式
if (dataGridView7.SelectedCells.Count > 0)
{
//MessageBox.Show(selcell + "------"+dataGridView7.CurrentCell.ColumnIndex.ToString());
if (selcell > 0 && dataGridView7.CurrentCell.ColumnIndex==0) { }else
{
selrow = dataGridView7.CurrentCell.RowIndex;
selcell = dataGridView7.CurrentCell.ColumnIndex;
}
}
loaddataJobsall();
dataGridView7.ClearSelection();
dataGridView7.Rows[selrow].Cells[selcell].Selected = true;
我正在创建一个 VB windows 应用程序。该应用程序的重点是一个简单的 DataGridView
,我从 SQL 服务器数据库中获取 View
。
DataGridView
每秒刷新一次,所以我可以在我的 GridView 中看到新的数据收入。
问题是在刷新后继续关注行。我需要解决方案,在我点击一行或一个单元格后,即使在刷新后它也会让我保持在上面。
这是我的代码:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Refresh every 1 sec
Dim timer As New Timer()
timer.Interval = 1000
AddHandler timer.Tick, AddressOf timer_Tick
timer.Start()
'TODO: This line of code loads data into the 'XYZDataSet.view1' table. You can move, or remove it, as needed.
Me.View1TableAdapter.Fill(Me.XYZDataSet.view1)
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
Private Sub DataGridView1_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
If Me.DataGridView1.Rows(i).Cells("DayTillDelivery").Value <= 30 Then
Me.DataGridView1.Rows(i).Cells("DayTillDelivery").Style.ForeColor = Color.Red
End If
Next
End Sub
Private Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
'Calling refresh after 1 second and updating the data
Me.DataGridView1.Refresh()
Me.View1TableAdapter.Fill(Me.XYZDataSet.view1)
End Sub
End Class
我过去解决了类似的问题,方法是在刷新之前将 selected 单元格的索引存储在一个变量中,因此我能够恢复 selection通过在更新后调用 DataGridView.Rows(selRow).Cells(selCol).Selected = True
。
编辑 - 示例代码:
To later readers:
Please take a look at Edit#2 where I describe a better method to re-select the previous selected cell!
示例代码:
' Variables for remembering the indexes of the selected cell
Dim selRow As Integer
Dim selCol As Integer
' Check if there is a selected cell to prevent NullPointerException
If DataGridView1.SelectedCells().Count > 0 Then
selRow = DataGridView1.CurrentCell.RowIndex
selCol = DataGridView1.CurrentCell.ColumnIndex
End If
' Dummy "update"
' don't forget to clear any existing rows before adding the new bunch (only if you always reloading all rows)!
DataGridView1.Rows.Clear()
For index = 1 To 20
DataGridView1.Rows.Add()
Next
' Check if there are "enough" rows after the update,
' to prevent setting the selection to an rowindex greater than the Rows.Count - 1 which would
' cause an IndexOutOfBoundsException
If (DataGridView1.Rows.Count - 1) > selRow Then
' Clear selection and then reselect the cell that was selected before by index
DataGridView1.ClearSelection()
' For the next line of code, there is a better solution in Edit #2!
DataGridView1.Rows(selRow).Cells(selCol).Selected = True
End If
请注意:
- 此过程要求您按照更新前添加行的顺序添加行,因为只有 selected 行的
.Index
存储在变量中。如果您以不同的顺序读取行,那么刷新后 select 将 select 编辑 相同位置 的行。 - 您应该添加检查是否有 selected 行(以防止
NullPointerException
)以及DataGridView
[=49] 中是否有“足够”的行=]在刷新后,防止出现IndexOutOfBoundsException
. - 这仅在
DataGridView1.SelectionMode
指向实际 select 行的内容时有效,例如FullRowSelect
。 - 在通过更新添加新行之前,不要忘记清除任何现有行(仅当您始终重新加载所有行时)。
编辑 2 - RowHeader 三角形和意外的 MultiSelect
如以下评论所述,如果用户按住鼠标按钮超过刷新周期,会出现一种奇怪的行为,会导致意外的多选。此外,RowHeader 三角形未设置为正确的行。
经过一番研究,我找到了解决此问题的方法。不要将给定单元格的 .Selected
-属性 设置为 True
,而是将 DataGridView
的 .CurrentCell
-属性 设置为您要设置的单元格想select!
在代码中,这意味着改变
DataGridView1.Rows(selRow).Cells(selCol).Selected = True
到
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol)
好了。 :-)
在填充之前,存储 CurrentRow 值和 currenCell 列:
Dim currentColumnIndex As Integer = 0 ;
Dim currentValues As List(Of Object) = If(DataGridView1.CurrentRow Is Nothing, Nothing, New List(Of Object)())
If currentValues IsNot Nothing Then
For i As Integer = 0 To DataGridView1.Columns.Count - 1
currentValues.Add(DataGridView1.CurrentRow.Cells(i).Value)
Next
currentColumnIndex = DataGridView1.CurrentCell.ColumnIndex;
End If
Fill后,搜索存储值对应的行:
Dim i As Integer = 0
While i < DataGridView1.Rows.Count AndAlso currentValues IsNot Nothing
Dim areIdentical As Boolean = True
Dim j As Integer = 0
While j < DataGridView1.Columns.Count AndAlso areIdentical
areIdentical = DataGridView1.Rows(i).Cells(j).Value = currentValues(j)
j += 1
End While
If areIdentical Then
DataGridView1.CurrentCell = DataGridView1.Rows(i).Cells(currentColumnIndex)
currentValues = Nothing
End If
i += 1
End While
注意:"For/While" 循环编码可能不是最佳的,因为它是从 C# 自动转换为 vb.net 的结果。
C# 修复代码,下一个重新加载模式
if (dataGridView7.SelectedCells.Count > 0)
{
//MessageBox.Show(selcell + "------"+dataGridView7.CurrentCell.ColumnIndex.ToString());
if (selcell > 0 && dataGridView7.CurrentCell.ColumnIndex==0) { }else
{
selrow = dataGridView7.CurrentCell.RowIndex;
selcell = dataGridView7.CurrentCell.ColumnIndex;
}
}
loaddataJobsall();
dataGridView7.ClearSelection();
dataGridView7.Rows[selrow].Cells[selcell].Selected = true;