Microsoft KB Archive/813832

= PRB: &quot;Index Was Out of Range&quot; Error Message from the DataGrid While Paging =

Article ID: 813832

Article Last Modified on 4/30/2003

-

APPLIES TO


 * Microsoft ASP.NET 1.0
 * Microsoft Visual Basic .NET 2002 Standard Edition
 * Microsoft Visual C# .NET 2002 Standard Edition
 * Microsoft ASP.NET 1.1
 * Microsoft Visual C# .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2003 Standard Edition

-





SYMPTOMS
To trap the record that is being accessed in a DataGrid Web server control, you use the DataKeys collection of DataGrid on an ItemCommand event, and then pass the ItemIndex property as a key to the DataKey collection. When you click a link to move to the next page (or to a new page) in the DataGrid, you may receive the following error message:

Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.



CAUSE
When you click a link to move to the next page (or to a new page) in the DataGrid, the ItemCommand event is invoked. The value of the ItemIndex property is -1 in the ItemCommand event. You may receive an error when you pass the ItemIndex property as a key to retrieve the value from the DataKey collection because the DataKey collection is zero bound.



WORKAROUND
To work around this problem, retrieve a value from the DataKey collection only when the value of the ItemIndex property is greater than or equal to 0. The following ItemCommand event sample code demonstrates how to do this.

Visual C# .NET Sample Code private void DataGrid1_ItemCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e) { // If Not navigating to Next Page, show the CategoryID in the text box. if (e.Item.ItemIndex > -1) { // Get the CategoryID of the Row Selected in the DataGrid. TextBox1.Text = DataGrid1.DataKeys[e.Item.ItemIndex].ToString; } } Visual Basic .NET code Private Sub DataGrid1_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.ItemCommand ' If Not navigating to Next Page, show the CategoryID in the text box. If e.Item.ItemIndex > -1 Then ' Get the CategoryID of the Row Selected in the DataGrid. TextBox1.Text = DataGrid1.DataKeys(e.Item.ItemIndex) End If  End Sub



STATUS
This behavior is by design.



Steps to Reproduce the Behavior
 Start Visual Studio .NET. On the File menu, point to New, and then click Project. In the New Project dialog box, under Project Types, click Visual C# Projects or Visual Basic Projects. Under Templates, click ASP.NET Web Application. In the Location text box, type MyDatagridTest, and then click OK. By default, WebForm1.aspx is created. Drag a DataGrid control from the toolbox to WebForm1. In Design view of WebForm1, right-click the DataGrid control, and then click Property Builder.</li> Click Paging, and then click to select the Allow Paging check box. In Page size textbox, type 4.

Note Verify for more than four records in the database.</li> Click Columns. In the Available columns list, expand Button Column.</li> Click the Select column, and then click the right arrow (>) to add the Select column to the Selected Columns list.</li> In the Textfield text box, type CategoryID.</li> Under Button Type, click LinkButton, and then click OK.</li> Drag a TextBox control from the toolbox to WebForm1.</li>  Double-click anywhere on WebForm1 to view the code for WebForm1.aspx. Replace the existing code with the following sample code:

Visual C# .NET Sample Code using System; using System.Data; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Data.SqlClient;

namespace MyDatagridTest {   ///     /// Summary description for WebForm1. ///    public class WebForm1 : System.Web.UI.Page {       protected System.Web.UI.WebControls.DataGrid DataGrid1; protected System.Web.UI.WebControls.TextBox TextBox1; private void Page_Load(object sender, System.EventArgs e)       { // Open a connection to the database. SqlConnection cn ; cn = new SqlConnection(&quot;data source=10.150.144.141;initial catalog=Northwind;User ID = sa;&quot;+               &quot;Password = sa; persist security info=False&quot;);

// Create a DataAdaptor for gaining access to data. SqlDataAdapter da ; da = new SqlDataAdapter(&quot;SELECT CategoryID, CategoryName, Description FROM Categories&quot;, cn);

// Populate the DataSet with data. DataSet ds = new DataSet; da.Fill(ds, &quot;Categories&quot;);

// Bind the Table to the DataGrid. DataGrid1.DataSource = ds.Tables[&quot;Categories&quot;].DefaultView;

// Specify the Column for DataKey. DataGrid1.DataKeyField = &quot;CategoryID&quot;; DataGrid1.DataBind; }

#region Web Form Designer generated code override protected void OnInit(EventArgs e)       { //           // CODEGEN: ASP.NET Web Form Designer requires this call. //           InitializeComponent; base.OnInit(e); }       ///         /// Required method for Designer support - do not change /// the contents of this method by using the code editor. ///        private void InitializeComponent {               this.DataGrid1.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_ItemCommand); this.DataGrid1.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.DataGrid1_PageIndexChanged); this.Load += new System.EventHandler(this.Page_Load);

}       #endregion private void DataGrid1_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)       { // Move to Next Page. DataGrid1.CurrentPageIndex = e.NewPageIndex; DataGrid1.DataBind; }

private void DataGrid1_ItemCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)       { // Get the CategoryID of the Row Selected in the DataGrid. TextBox1.Text = DataGrid1.DataKeys[e.Item.ItemIndex].ToString; }

} } Visual Basic .NET code Imports System.Data.SqlClient

Public Class WebForm1 Inherits System.Web.UI.Page Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid


 * 1) Region &quot; Web Form Designer Generated Code &quot;

'The Web Form Designer requires this call. <System.Diagnostics.DebuggerStepThrough> Private Sub InitializeComponent

End Sub

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: The Web Form Designer requires this method call. 'Do not change it by using the code editor. InitializeComponent End Sub


 * 1) End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Open a connection to the database. Dim cn As SqlConnection cn = New SqlConnection(&quot;data source=10.150.144.131;initial catalog=Northwind;User ID = sa; persist security info=False&quot;)

' Create a DataAdaptor for gaining access to data. Dim da As SqlDataAdapter da = New System.Data.SqlClient.SqlDataAdapter(&quot;SELECT CategoryID, CategoryName, Description FROM Categories&quot;, cn)

' Populate the DataSet with data. Dim ds As New DataSet da.Fill(ds, &quot;Categories&quot;)

' Bind the Table to the DataGrid. DataGrid1.DataSource = ds.Tables(&quot;Categories&quot;).DefaultView ' Specify the Column for DataKey DataGrid1.DataKeyField = &quot;CategoryID&quot; DataGrid1.DataBind End Sub

Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged ' Move to Next Page. DataGrid1.CurrentPageIndex = e.NewPageIndex DataGrid1.DataBind End Sub

Private Sub DataGrid1_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.ItemCommand ' Get the CategoryID of the Row Selected in the DataGrid. TextBox1.Text = DataGrid1.DataKeys(e.Item.ItemIndex) End Sub

End Class </li> On the Debug menu, click Start to run the application.</li> Click any record link, for example, 2. The value 2 appears in the text box.</li> Click the right arrow (>) to move to the next page of records. The error message mentioned in the &quot;Symptoms&quot; section appears.</li></ol>

<div class="references_section">