提问人:Manish Kharotia 提问时间:2/2/2023 最后编辑:James ZManish Kharotia 更新时间:2/3/2023 访问量:57
请帮助指数超出范围。必须是非负数
Kindly help Index was out of range. Must be non-negative
问:
<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 '
答:
让我们把卡车放在这里。
首先,没有理由用所有这些值填充数据键。您在网格中有这些值,因此,实际上不需要将它们再次放入数据键中。
数据键作为流派规则,应仅保存数据库主键“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 将启动,并“提供”您创建简单的按钮单击。
它有效,如下所示:
因此,这是我们的 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 中的所有控件,并从单个数据行中推入值。
评论
gvUnitNomRoll.DataKeys
gvUnitNomRoll.DataKeys(4)