请帮忙索引超出范围。必须是非负数

问题描述 投票:0回答:1
<asp:GridView ID="gvUnitNomRoll" runat="server"  OnRowCommand ="gvUnitNomRoll_RowCommand1"  SkinID="gridviewSkin" Width="100%"
    DataKeyNames="id, name, desig, idr, service" EmptyDataText="" AutoGenerateColumns="false">
    <Columns>
        <asp:TemplateField HeaderText="Sl" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate> <%#Ctype (Container, GridViewRow).RowIndex+1 %></ItemTemplate>
        </asp:TemplateField>
          <asp:BoundField HeaderText="id" DataField="name" Visible ="false"/>
        <asp:BoundField HeaderText="Name" DataField="name"/>
        <asp:BoundField HeaderText="desig" DataField="desig" />
        <asp:BoundField HeaderText="Idr" DataField="idr" />
        <asp:BoundField HeaderText="Service" DataField="service" />
       <asp:ButtonField ButtonType="Button" CommandName="ed" ControlStyle-CssClass ="allBtn blue"  HeaderText="Update Details" 
           ItemStyle-HorizontalAlign="Center" ItemStyle-Width="80px" Text="Update" />                                        
        <asp:ButtonField ButtonType="Button" CommandName="tfrOut" ControlStyle-CssClass ="allBtn red"  
            HeaderText="Transfer" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="80px" Text="Transfer Out" />                                        
        <asp:ButtonField ButtonType="Button" CommandName="Verify" ControlStyle-CssClass ="allBtn green" 
            HeaderText="Verify" ItemStyle-HorizontalAlign="Center"  ItemStyle-Width="80px" Text="Verify" />  


    </Columns>
</asp:GridView>

这是我的vb.code

Dim CmdName As String = e.CommandName
Dim nInt As Integer = Convert.ToInt32(e.CommandArgument)
Dim currentPno As String = gvUnitNomRoll.DataKeys(nInt).Item("id").ToString() 'Here throws error ' 
If (e.CommandName = "ed") Then
    If currentPno <> "" Then

它抛出错误

索引超出范围。必须为非负数且小于集合的大小。参数名称:索引

调试时

Dim currentPno As String = gvUnitNomRoll.DataKeys(nInt).Item("id").ToString() 'Here throws error '
asp.net vb.net gridview
1个回答
0
投票

让我们回到这里。

首先,没有什么理由用所有这些值填充数据键。您在网格中拥有这些值,因此,不需要将它们再次放入数据键中。

Datakeys 作为一般规则应该只保存数据库主键“ID”。

Daykeys 很好,因为这样你就不必显示/包含/拥有/担心在 GV 中显示该 ID(用户不需要查看或关心)。事实上,出于安全原因,您不需要也不想在该 gv 中包含数据库 PK id(这就是数据密钥的全部意义)。

此外,我没有看到您在任何地方设置命令参数,但您随后尝试将命令参数拉入 int 值(因此,这就是您的代码失败的地方)。

那么,一般来说,如果您想要在 GV 中单击一个简单的按钮?

然后只需放入一个简单的简常规按钮即可。它们工作得更好,易于使用,而且你最好怀疑过去使用好的旧 asp.net 按钮。

所以,我没有您的数据,但让我们加载一个包含一些数据行(酒店)的 gv。然后在gv中添加一个按钮click,然后获取用户点击的那一行数据

<h3>Hotels</h3>
<asp:GridView ID="GridView1" runat="server" Width="40%"
    AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table" >
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
        <asp:BoundField DataField="LastName" HeaderText="LastName" />
        <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
        <asp:BoundField DataField="City" HeaderText="City" />
        <asp:BoundField DataField="Description" HeaderText="Description" />
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Button ID="cmdEdit" runat="server" Text="Edit"
                    CssClass="btn"
                    onclick="cmdEdit_Click" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

因此,使用“模板”字段,在其中,您可以放置任何标准平面 Jane asp.net 控件 - 包括按钮的控件。

现在,在大多数情况下,当我们将按钮拖放到 Web 表单中时,我们可以双击该按钮来连接单击事件。但是,由于按钮“嵌套”在 gv 内部,因此我们无法轻松双击按钮,并跳转到存根后面的代码。

因此,在标记视图中,简单地输入 onclick=。

当您点击“=”时,IntelliSense 将启动,并“提供”您创建简单的按钮单击。

Tt 有效,看起来像这样:

所以,这是我们的 gv 标记:

<h3>Hotels</h3>
<asp:GridView ID="GridView1" runat="server" Width="40%"
    AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table" >
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
        <asp:BoundField DataField="LastName" HeaderText="LastName" />
        <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
        <asp:BoundField DataField="City" HeaderText="City" />
        <asp:BoundField DataField="Description" HeaderText="Description" />
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Button ID="cmdEdit" runat="server" Text="Edit"
                    CssClass="btn"
                    OnClick="cmdEdit_Click"
                     />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

我们加载 GV 的代码是这样的:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadData()
    End If

End Sub


Sub LoadData()

    Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName"
    Dim cmdSQL As New SqlCommand(strSQL)
    GridView1.DataSource = MyrstP(cmdSQL)
    GridView1.DataBind()

End Sub

好的,现在我们需要该按钮单击的事件代码:

Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)

    Dim btn As Button = sender
    Dim gRow As GridViewRow = btn.NamingContainer
    Dim intPK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")

    Dim cmdSQL = New SqlCommand("SELECT * FROM tblHotelsA WHERE ID = @ID")
    cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = intPK
    Dim rstHotel As DataTable = MyrstP(cmdSQL)

    Debug.Print($"Row click = {gRow.RowIndex}")
    Debug.Print($"Data base PK id (data keys) = {intPK}")
    Debug.Print($"Hotel Name from gv = {gRow.Cells(2).Text}")

    If rstHotel.Rows.Count > 0 Then
        Call EditOne(rstHotel.Rows(0))
    End If


End Sub

所以,上面的输出是这样的:

然后单击行按钮,我们得到:

Row click = 5
Data base PK id (data keys) = 3
Hotel Name from gv = Sandman Inn

当然我有一个例程,叫做“Editone”。所做的只是隐藏 GV,显示带有标准控件的 div,以及一些填充控件的代码。

所以,编辑一个看起来像:

Sub EditOne(MyRow As DataRow)

    ViewState("PKID") = MyRow("ID")
    fLoader(EditRecord, MyRow)
    GridView1.Visible = False
    EditRecord.Visible = True

End Sub

所以,现在我们看到/明白了:

“fLoader”是一个例程,它循环该 div 中的所有控件,并推入一个数据行中的值。

© www.soinside.com 2019 - 2024. All rights reserved.