请帮助指数超出范围。必须是非负数

Kindly help Index was out of range. Must be non-negative

提问人:Manish Kharotia 提问时间:2/2/2023 最后编辑:James ZManish Kharotia 更新时间:2/3/2023 访问量:57

问:

<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

它抛出错误

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

调试时

Dim currentPno As String = gvUnitNomRoll.DataKeys(nInt).Item("id").ToString() 'Here throws error '
asp.net vb.net gridview

评论

0赞 jmcilhinney 2/2/2023
请使用您提供的问题的预览,如果格式混乱,请不要提交。您需要编辑问题并对其进行清理,以便我们可以轻松阅读。此外,您需要提供对问题的完整和清晰的解释,而不仅仅是代码中的注释。请花一些时间在帮助中心学习如何提出适当的问题。
0赞 Manish Kharotia 2/2/2023
好的,先生。我也会这样做
0赞 Manish Kharotia 2/2/2023
我已经格式化了代码。现在请帮帮我
0赞 James Z 2/2/2023
显然,它说索引是错误的。那么 nInt 的价值是什么呢?这就是你应该在问题中提到的那种事情。
1赞 Andrew Morton 2/3/2023
如果有 5 个元素,那么最后一个元素将是 ,如果有帮助的话。gvUnitNomRoll.DataKeysgvUnitNomRoll.DataKeys(4)

答:

0赞 Albert D. Kallal 2/3/2023 #1

让我们把卡车放在这里。

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

数据键作为流派规则,应仅保存数据库主键“ID”。

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

此外,我没有看到您设置命令 arument 的任何地方,但您随后将命令增强拉入 int 值(所以,这就是您的代码失败的地方)。

所以,一般来说,如果你想要在 GV 中单击一个简单的按钮?

然后只需放入一个普通的简常规按钮即可。它们工作得更好,易于使用,而且你过去使用普通的 jane good old asp.net 按钮。

所以,我没有你的数据,但让我们加载一个包含一些数据行(酒店)的 gv。然后,将按钮单击添加到 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>

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

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

因此,在标记视图中,只需键入 onclick=。

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

它有效,如下所示:

enter image description here

因此,这是我们的 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

因此,上面的输出是这样的:

enter image description here

单击一行按钮,我们得到:

输出:

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

所以,现在我们看到/得到这个:

enter image description here

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