如何通过 DataGridView 行连续循环?
How to cycle continuously through DataGridView rows?
这似乎是一个重复的问题,但我正在寻找一个特定的函数。我在 Whosebug 和 Google 上查看了类似的问题,并尝试使用许多不同的代码示例,但到目前为止,都没有成功?
我在做什么:
- 在运行时,即
Form1_Load
,我调用一个函数在 DataGridView 中显示“MyFolder”中所有文件的文件信息。
- 我使用 Next/Previous 按钮循环浏览 DGV 行。
我的代码:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
'Call Function To Display File Info From MyFolder:
DataGridView1.DataSource = Fileinfo_To_DataTable("C:\Users\" + username + "\Documents\MyApp\MyFolder")
End Sub
'Next Button:
Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
If DataGridView1.SelectedRows(0).Index < DataGridView1.RowCount - 1 Then
MyDesiredIndex = DataGridView1.SelectedRows(0).Index + 1
Else
MyDesiredIndex = 0
End If
DataGridView1.ClearSelection()
DataGridView1.CurrentCell = DataGridView1.Rows(MyDesiredIndex).Cells(0)
DataGridView1.Rows(MyDesiredIndex).Selected = True
End Sub
'Previous Button:
Private Sub btnPrev_Click(sender As Object, e As EventArgs) Handles btnPrev.Click
If DataGridView1.CurrentCell.RowIndex >= 0 And DataGridView1.CurrentCell.RowIndex <= DataGridView1.Rows.Count - 1 Then
For Each row As DataGridViewRow In DataGridView1.Rows
If Not row.IsNewRow Or vbNull Then
MyDesiredIndex = DataGridView1.SelectedRows(0).Index - 1
End If
Next
End If
DataGridView1.ClearSelection()
DataGridView1.CurrentCell = DataGridView1.Rows(MyDesiredIndex).Cells(0)
DataGridView1.Rows(MyDesiredIndex).Selected = True
End Sub
问题:
Next 按钮在“连续循环”中无一例外地循环所有 DGV 行。 “连续循环”是指我的程序在第一行 (0) 或最后一行不停地循环遍历所有行(即,只要我继续按下下一步按钮,就会发生循环)。
Previous 按钮仅在我首先使用 Next 按钮更改所选行(即 First > Last)时才有效。然后,点击 Previous 按钮将所选行更改为第一行(即 Last > First)。但是,当程序到达第一行时,它抛出如下异常:
"System.ArgumentOutOfRangeException: 'Index was out of range. Must be
non-negative and less than the size of the collection. Parameter name:
index'"
- 解决超出范围异常。
- 解决cycling/looping遍历所有行的问题?
我试过的:
除了我上面的尝试(以及许多其他尝试),我在 Whosebug 上发现了以下代码,它解决了同样的问题,但它也在第一行停止而不循环遍历所有行:
移动到数据网格视图中的上一行
Moving to previous row in datagridview
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer = DataGridView1.CurrentRow.Index - 1
If i < 0 Then i = 0
DataGridView1.CurrentCell = Me.DataGridView1.Rows(i).Cells(0)
DataGridView1.Rows(i).Selected = True
End Sub
期望的行为:
我将不胜感激任何帮助使 Previous 按钮的行为与 Next 按钮相同的方式,即连续循环所有行而不抛出异常。
我曾多次尝试寻找逻辑来“包含”范围内先前行的选择,但没有成功。但是,我真的很喜欢 Next 按钮不间断地连续循环遍历行的方式,并且想将此行为复制到 Previous 按钮以便能够不间断地连续双向循环(即 Next/Previous)?我也尝试了几种不同的 For Each
循环,但无法让代码以所需的方式工作?
有人知道我该如何实现吗?
使用 BindingSource as mediator between your data source of FileInfo objects and the DataGridView, you can directly make use of the BindingSource, MovePrevious(), MoveNext(), MoveFirst() and MoveLast() 方法。
请注意,所有这些都是void
方法(Sub
),none returns一个状态,但是你可以使用 Position 属性.
确定数据源中的当前位置
- 使用 Environment.GetFolderPath() method to get the path of Special Folders as the current User's Documents folder. The Environment.SpecialFolder 枚举用于引用这些路径之一。
- 始终使用 Path.Combine() 构建路径。
- 将 BindingSource 对象声明为 Field,以便您以后可以轻松访问它。
- 在
OnLoad()
方法覆盖(或 Form.Load
事件处理程序,如您所愿)中,创建 FileInfo
对象的集合,将此集合设置为 BindingSource 的 DataSource 和将 BindingSource 作为 DataGridView 的数据源:
Private fileListSource As BindingSource = Nothing
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Dim docsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim filesPath = Path.Combine(docsPath, "MyApp\MyFolder")
fileListSource = New BindingSource(New DirectoryInfo(filesPath).GetFiles("*.txt"), Nothing)
DataGridView1.DataSource = fileListSource
End Sub
现在,您可以使用四个按钮来移动 Current
对象(另见 CurrencyManager class),使用 BindingSource 的上述方法,检查 Current
对象的位置,以确定在单击“下一个”或“上一个”按钮时是否必须 Current
移动到第一个或最后一个对象:
Private Sub btnMoveFirst_Click(sender As Object, e As EventArgs) Handles btnMoveFirst.Click
fileListSource.MoveFirst()
End Sub
Private Sub btnMoveLast_Click(sender As Object, e As EventArgs) Handles btnMoveLast.Click
fileListSource.MoveLast()
End Sub
Private Sub btnMovePrevious_Click(sender As Object, e As EventArgs) Handles btnMovePrevious.Click
If fileListSource.Position > 0 Then
fileListSource.MovePrevious()
Else
fileListSource.MoveLast()
End If
End Sub
Private Sub btnMoveNext_Click(sender As Object, e As EventArgs) Handles btnMoveNext.Click
If fileListSource.Position < fileListSource.Count - 1 Then
fileListSource.MoveNext()
Else
fileListSource.MoveFirst()
End If
End Sub
它是这样工作的:
这里是未过滤的文件列表
使用 DataBinding,您可以将其他控件绑定到 BindingSource 并与其数据源交互,在本例中为 FileInfo 对象的集合。
这意味着当您更改绑定控件的 属性 值时,集合中当前对象的属性也会更改。
由于您有 FileInfo 对象,这会自动反映在基础 File 对象上,从而更改其属性。
这里,ReadOnly
、CreationTime
和 LastWriteTime
使用一个 CheckBox 和两个 DateTimePickers 进行更改。
dtpLastWrite.DataBindings.Add("Value", fileListSource, "LastWriteTime", True, DataSourceUpdateMode.OnPropertyChanged)
dtpCreationTime.DataBindings.Add("Value", fileListSource, "CreationTime", False, DataSourceUpdateMode.OnPropertyChanged)
chkReadOnly.DataBindings.Add("Checked", fileListSource, "IsReadOnly", False, DataSourceUpdateMode.OnPropertyChanged)
这似乎是一个重复的问题,但我正在寻找一个特定的函数。我在 Whosebug 和 Google 上查看了类似的问题,并尝试使用许多不同的代码示例,但到目前为止,都没有成功?
我在做什么:
- 在运行时,即
Form1_Load
,我调用一个函数在 DataGridView 中显示“MyFolder”中所有文件的文件信息。 - 我使用 Next/Previous 按钮循环浏览 DGV 行。
我的代码:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
'Call Function To Display File Info From MyFolder:
DataGridView1.DataSource = Fileinfo_To_DataTable("C:\Users\" + username + "\Documents\MyApp\MyFolder")
End Sub
'Next Button:
Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
If DataGridView1.SelectedRows(0).Index < DataGridView1.RowCount - 1 Then
MyDesiredIndex = DataGridView1.SelectedRows(0).Index + 1
Else
MyDesiredIndex = 0
End If
DataGridView1.ClearSelection()
DataGridView1.CurrentCell = DataGridView1.Rows(MyDesiredIndex).Cells(0)
DataGridView1.Rows(MyDesiredIndex).Selected = True
End Sub
'Previous Button:
Private Sub btnPrev_Click(sender As Object, e As EventArgs) Handles btnPrev.Click
If DataGridView1.CurrentCell.RowIndex >= 0 And DataGridView1.CurrentCell.RowIndex <= DataGridView1.Rows.Count - 1 Then
For Each row As DataGridViewRow In DataGridView1.Rows
If Not row.IsNewRow Or vbNull Then
MyDesiredIndex = DataGridView1.SelectedRows(0).Index - 1
End If
Next
End If
DataGridView1.ClearSelection()
DataGridView1.CurrentCell = DataGridView1.Rows(MyDesiredIndex).Cells(0)
DataGridView1.Rows(MyDesiredIndex).Selected = True
End Sub
问题:
Next 按钮在“连续循环”中无一例外地循环所有 DGV 行。 “连续循环”是指我的程序在第一行 (0) 或最后一行不停地循环遍历所有行(即,只要我继续按下下一步按钮,就会发生循环)。
Previous 按钮仅在我首先使用 Next 按钮更改所选行(即 First > Last)时才有效。然后,点击 Previous 按钮将所选行更改为第一行(即 Last > First)。但是,当程序到达第一行时,它抛出如下异常:
"System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'"
- 解决超出范围异常。
- 解决cycling/looping遍历所有行的问题?
我试过的:
除了我上面的尝试(以及许多其他尝试),我在 Whosebug 上发现了以下代码,它解决了同样的问题,但它也在第一行停止而不循环遍历所有行:
移动到数据网格视图中的上一行
Moving to previous row in datagridview
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer = DataGridView1.CurrentRow.Index - 1
If i < 0 Then i = 0
DataGridView1.CurrentCell = Me.DataGridView1.Rows(i).Cells(0)
DataGridView1.Rows(i).Selected = True
End Sub
期望的行为:
我将不胜感激任何帮助使 Previous 按钮的行为与 Next 按钮相同的方式,即连续循环所有行而不抛出异常。
我曾多次尝试寻找逻辑来“包含”范围内先前行的选择,但没有成功。但是,我真的很喜欢 Next 按钮不间断地连续循环遍历行的方式,并且想将此行为复制到 Previous 按钮以便能够不间断地连续双向循环(即 Next/Previous)?我也尝试了几种不同的 For Each
循环,但无法让代码以所需的方式工作?
有人知道我该如何实现吗?
使用 BindingSource as mediator between your data source of FileInfo objects and the DataGridView, you can directly make use of the BindingSource, MovePrevious(), MoveNext(), MoveFirst() and MoveLast() 方法。
请注意,所有这些都是void
方法(Sub
),none returns一个状态,但是你可以使用 Position 属性.
- 使用 Environment.GetFolderPath() method to get the path of Special Folders as the current User's Documents folder. The Environment.SpecialFolder 枚举用于引用这些路径之一。
- 始终使用 Path.Combine() 构建路径。
- 将 BindingSource 对象声明为 Field,以便您以后可以轻松访问它。
- 在
OnLoad()
方法覆盖(或Form.Load
事件处理程序,如您所愿)中,创建FileInfo
对象的集合,将此集合设置为 BindingSource 的 DataSource 和将 BindingSource 作为 DataGridView 的数据源:
Private fileListSource As BindingSource = Nothing
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Dim docsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim filesPath = Path.Combine(docsPath, "MyApp\MyFolder")
fileListSource = New BindingSource(New DirectoryInfo(filesPath).GetFiles("*.txt"), Nothing)
DataGridView1.DataSource = fileListSource
End Sub
现在,您可以使用四个按钮来移动 Current
对象(另见 CurrencyManager class),使用 BindingSource 的上述方法,检查 Current
对象的位置,以确定在单击“下一个”或“上一个”按钮时是否必须 Current
移动到第一个或最后一个对象:
Private Sub btnMoveFirst_Click(sender As Object, e As EventArgs) Handles btnMoveFirst.Click
fileListSource.MoveFirst()
End Sub
Private Sub btnMoveLast_Click(sender As Object, e As EventArgs) Handles btnMoveLast.Click
fileListSource.MoveLast()
End Sub
Private Sub btnMovePrevious_Click(sender As Object, e As EventArgs) Handles btnMovePrevious.Click
If fileListSource.Position > 0 Then
fileListSource.MovePrevious()
Else
fileListSource.MoveLast()
End If
End Sub
Private Sub btnMoveNext_Click(sender As Object, e As EventArgs) Handles btnMoveNext.Click
If fileListSource.Position < fileListSource.Count - 1 Then
fileListSource.MoveNext()
Else
fileListSource.MoveFirst()
End If
End Sub
它是这样工作的:
这里是未过滤的文件列表
使用 DataBinding,您可以将其他控件绑定到 BindingSource 并与其数据源交互,在本例中为 FileInfo 对象的集合。
这意味着当您更改绑定控件的 属性 值时,集合中当前对象的属性也会更改。
由于您有 FileInfo 对象,这会自动反映在基础 File 对象上,从而更改其属性。
这里,ReadOnly
、CreationTime
和 LastWriteTime
使用一个 CheckBox 和两个 DateTimePickers 进行更改。
dtpLastWrite.DataBindings.Add("Value", fileListSource, "LastWriteTime", True, DataSourceUpdateMode.OnPropertyChanged)
dtpCreationTime.DataBindings.Add("Value", fileListSource, "CreationTime", False, DataSourceUpdateMode.OnPropertyChanged)
chkReadOnly.DataBindings.Add("Checked", fileListSource, "IsReadOnly", False, DataSourceUpdateMode.OnPropertyChanged)