GridView1.SelectedIndex索引越界异常问题求助
问题描述
- 在
GridView1_SelectedIndexChanged函数内可正常获取选中行,但在其他函数中访问GridView1.SelectedRow会触发索引越界异常 - 点击GridView的选择按钮后,整个GridView会消失
- 尝试重新绑定GridView也无法解决上述问题
后端代码
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then ' Only add the event handler on initial page load AddHandler GridView1.SelectedIndexChanged, AddressOf GridView1_SelectedIndexChanged GridView1.DataBind() End If End Sub 'Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles GridView1.SelectedIndexChanged ' Try ' If GridView1.SelectedIndex <> -1 Then ' UpdateButtonVisibility() ' Dim itemSelected As GridViewRow = GridView1.SelectedRow ' Dim acoo As String = itemSelected.Cells(1).Text ' Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("ExtranetConnectionString").ConnectionString) ' Dim query As String = "Select InvoiceAttach FROM TblInvoice WHERE CertificateId=@acoo" ' Using sqlCmd As New SqlCommand(query, conn) ' sqlCmd.Parameters.Add(New SqlParameter("acoo", acoo)) ' conn.Open() ' Dim reader As SqlDataReader = sqlCmd.ExecuteReader() ' If reader.HasRows Then ' reader.Read() ' 'url = "/Files/" & reader("InvoiceAttach") ' url = reader("InvoiceAttach") & "" ' Dim s As String = "window.open('" & url + "', 'popup_window', 'width=500,height=800,left=100,top=100,resizable=yes');" ' ClientScript.RegisterStartupScript(Me.GetType(), "script", s, True) ' End If ' ' End Using ' End If ' Catch ex As Exception ' MsgBox(ex.Message) ' End Try ' GridView1.DataBind() 'End Sub
前端代码
<asp:GridView ID="GridView1" runat="server" CssClass="table" EnableViewState="true" AutoGenerateColumns="False" AutoPostBack="True" DataSourceID="SqlDataSource1" AllowPaging="True" AllowSorting="True" CellPadding="4" ForeColor="#333333" GridLines="None"> <AlternatingRowStyle BackColor="White" ForeColor="#284775" /> <Columns> <asp:CommandField ShowSelectButton="True" /> <asp:BoundField DataField="Acoo" HeaderText="Acoo" InsertVisible="False" ReadOnly="True" SortExpression="Acoo" /> <asp:BoundField DataField="Tp" HeaderText="Tp" SortExpression="Tp" /> <asp:BoundField DataField="Idno" HeaderText="Idno" SortExpression="Idno" /> <asp:BoundField DataField="Status" HeaderText="Status" SortExpression="Status" /> <asp:BoundField DataField="invoicenumber" HeaderText="invoicenumber" SortExpression="invoicenumber" /> <asp:BoundField DataField="invoicedate" HeaderText="invoicedate" SortExpression="invoicedate" /> </Columns> <EditRowStyle BackColor="#999999" /> <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" /> <RowStyle BackColor="#F7F6F3" ForeColor="#333333" /> <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" /> <SortedAscendingCellStyle BackColor="#E9E7E2" /> <SortedAscendingHeaderStyle BackColor="#506C8C" /> <SortedDescendingCellStyle BackColor="#FFFDF8" /> <SortedDescendingHeaderStyle BackColor="#6F8DAE" /> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ExtranetConnectionString %>" SelectCommand="SELECT Acoo, Tp, Idno, Status, invoicenumber, invoicedate FROM TblACOO WHERE (Status = 4) AND (Tp = @Tp) AND (Idno = @Idno) ORDER BY invoicedate DESC"> <SelectParameters> <asp:FormParameter FormField="type" Name="Tp" Type="Int32" /> <asp:FormParameter FormField="idno" Name="Idno" Type="Int32" /> </SelectParameters> </asp:SqlDataSource>
问题原因分析
- GridView消失:
SqlDataSource1使用FormParameter获取type和idno参数,PostBack时表单字段值可能丢失或未传递,导致查询无结果,GridView因无数据显示消失。 - 索引越界异常:PostBack后GridView无数据但
SelectedIndex状态仍保留,此时访问SelectedRow会因实际无行数据触发异常;同时Page_Load仅在首次加载绑定,PostBack时参数失效导致绑定也拿不到数据。
修复步骤
1. 确保PostBack时参数不丢失
将FormParameter替换为SessionParameter,先在首次加载时把表单值存入Session:
' Page_Load修改 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Session("Tp") = Request.Form("type") Session("Idno") = Request.Form("idno") GridView1.DataBind() End If End Sub
<!-- SqlDataSource参数修改 --> <SelectParameters> <asp:SessionParameter SessionField="Tp" Name="Tp" Type="Int32" /> <asp:SessionParameter SessionField="Idno" Name="Idno" Type="Int32" /> </SelectParameters>
2. 移除重复事件绑定
GridView已通过Handles关键字绑定事件,无需手动AddHandler,修改Page_Load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then ' 移除AddHandler代码 GridView1.DataBind() End If End Sub
3. 访问SelectedRow前做判断
在任何需要访问GridView1.SelectedRow的代码前,先检查数据是否存在:
If GridView1.Rows.Count > 0 AndAlso GridView1.SelectedIndex <> -1 Then Dim itemSelected As GridViewRow = GridView1.SelectedRow ' 后续业务逻辑 Else ' 处理无数据或未选中的情况 End If
4. 移除SelectedIndexChanged中的重复绑定
原注释代码最后调用的GridView1.DataBind()会导致选中状态丢失,建议删除该行,SqlDataSource绑定的GridView会自动维护状态。
内容的提问来源于stack exchange,提问作者CCIABML
相关产品推荐
相关产品推荐

