VB.Net索引超出范围问题求助:将frm_Guest选中行传入frm_Main报错
Let's break down why you're hitting those errors and how to fix them quickly. The "Must be non-negative and less than the size of the collection" and "Index was out of range" messages mean your code is trying to access a row that doesn't exist (or isn't selected) in your DataGridView.
What's Causing the Issue?
This usually happens for one of these reasons:
- Clicking a cell doesn't automatically select the entire row (depends on your DataGridView's settings)
- You clicked the header row or an empty area of the grid instead of a data row
- The grid has no rows loaded when the click happens
- Your code tries to access
SelectedRows(0)even when no rows are selected
Step-by-Step Fixes
1. Add a Safety Check for Selected Rows
First, always validate that at least one row is selected before trying to pull data from it. This prevents the index error entirely:
Private Sub dgview_GPIGuest_CellContentClick_1(sender As Object, e As DataGridViewCellEventArgs) Handles dgview_GPIGuest.CellContentClick ' Make sure we're clicking a valid data row and a row is selected If dgview_GPIGuest.SelectedRows.Count > 0 AndAlso e.RowIndex >= 0 Then Dim selectedRow As DataGridViewRow = dgview_GPIGuest.SelectedRows(0) ' Safely retrieve values (handle empty cells to avoid null errors) Dim ID As String = If(selectedRow.Cells(0).Value Is DBNull.Value, "", selectedRow.Cells(0).Value.ToString()) Dim FName As String = If(selectedRow.Cells(1).Value Is DBNull.Value, "", selectedRow.Cells(1).Value.ToString()) Dim LName As String = If(selectedRow.Cells(2).Value Is DBNull.Value, "", selectedRow.Cells(2).Value.ToString()) Dim Gender As String = If(selectedRow.Cells(3).Value Is DBNull.Value, "", selectedRow.Cells(3).Value.ToString()) ' Pass data to frm_Main (adjust this part to match how you open/access frm_Main) Dim mainForm As frm_Main = DirectCast(Application.OpenForms("frm_Main"), frm_Main) mainForm.UpdateGuestDetails(ID, FName, LName, Gender) Else ' Optional: Let the user know they need to select a row MessageBox.Show("Please select a guest row first!") End If End Sub
2. Make Clicking a Cell Select the Entire Row
If clicking a cell doesn't select the whole row, adjust your DataGridView's selection mode. You can do this in the designer or via code:
In the Designer:
- Select
dgview_GPIGuest - Go to Properties > SelectionMode
- Choose
FullRowSelect(clicks anywhere on the row select it) orRowHeaderSelect(only clicks on the row header select the row)
Via Code (add to your form's Load event):
Private Sub frm_Guest_Load(sender As Object, e As EventArgs) Handles MyBase.Load dgview_GPIGuest.SelectionMode = DataGridViewSelectionMode.FullRowSelect dgview_GPIGuest.MultiSelect = False ' Optional: Prevent selecting multiple rows if not needed End Sub
3. Use the Clicked Row Directly (Alternative Approach)
Instead of relying on SelectedRows, you can grab the row directly from the click event arguments. This is more reliable if selection isn't your main goal:
Private Sub dgview_GPIGuest_CellContentClick_1(sender As Object, e As DataGridViewCellEventArgs) Handles dgview_GPIGuest.CellContentClick ' Check if we're clicking a valid data row (not the header) If e.RowIndex >= 0 Then Dim clickedRow As DataGridViewRow = dgview_GPIGuest.Rows(e.RowIndex) ' Retrieve values safely Dim ID As String = If(clickedRow.Cells(0).Value Is DBNull.Value, "", clickedRow.Cells(0).Value.ToString()) ' ... repeat for other fields ' Pass to frm_Main ' ... End If End Sub
Bonus: Handle Empty Cells
Notice the If(selectedRow.Cells(0).Value Is DBNull.Value, "", ...) check? This prevents null reference errors if a cell has no data. It's a small addition that saves you from more headaches down the line.
内容的提问来源于stack exchange,提问作者Mark Asuncion

