Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

PRB: "Index Was Out of Range" Error Message from the DataGrid While Paging


View products that this article applies to.

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.

↑ Back to the top


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.

↑ Back to the top


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

↑ Back to the top


Status

This behavior is by design.

↑ Back to the top


More information

Steps to Reproduce the Behavior

  1. Start Visual Studio .NET. On the File menu, point to New, and then click Project.
  2. In the New Project dialog box, under Project Types, click Visual C# Projects or Visual Basic Projects. Under Templates, click ASP.NET Web Application.
  3. In the Location text box, type MyDatagridTest, and then click OK. By default, WebForm1.aspx is created.
  4. Drag a DataGrid control from the toolbox to WebForm1.
  5. In Design view of WebForm1, right-click the DataGrid control, and then click Property Builder.
  6. 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.
  7. Click Columns. In the Available columns list, expand Button Column.
  8. Click the Select column, and then click the right arrow (>) to add the Select column to the Selected Columns list.
  9. In the Textfield text box, type CategoryID.
  10. Under Button Type, click LinkButton, and then click OK.
  11. Drag a TextBox control from the toolbox to WebForm1.
  12. 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>
    	/// Summary description for WebForm1.
    	/// </summary>
    	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("data source=10.150.144.141;initial catalog=Northwind;User ID = sa;"+				"Password = sa; persist security info=False");
    
    			// Create a DataAdaptor for gaining access to data.
    			SqlDataAdapter da ;
    			da = new SqlDataAdapter("SELECT CategoryID, CategoryName, Description FROM Categories", cn);
    
    			//  Populate the DataSet with data.
    			DataSet ds = new DataSet();
    			da.Fill(ds, "Categories"); 
    
    			//  Bind the Table to the DataGrid.
    			DataGrid1.DataSource = ds.Tables["Categories"].DefaultView;
    
    			//  Specify the Column for DataKey.
    			DataGrid1.DataKeyField = "CategoryID";
    			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);
    		}
    		
    		/// <summary>
    		/// Required method for Designer support - do not change
    		/// the contents of this method by using the code editor.
    		/// </summary>
    		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
    
    #Region " Web Form Designer Generated Code "
    
       '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
    
    #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("data source=10.150.144.131;initial catalog=Northwind;User ID = sa; persist security info=False")
    
          ' Create a DataAdaptor for gaining access to data.
          Dim da As SqlDataAdapter
          da = New System.Data.SqlClient.SqlDataAdapter("SELECT CategoryID, CategoryName, Description FROM Categories", cn)
    
          ' Populate the DataSet with data.
          Dim ds As New DataSet()
          da.Fill(ds, "Categories")
    
          ' Bind the Table to the DataGrid.
          DataGrid1.DataSource = ds.Tables("Categories").DefaultView
          ' Specify the Column for DataKey
          DataGrid1.DataKeyField = "CategoryID"
          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
  13. On the Debug menu, click Start to run the application.
  14. Click any record link, for example, 2. The value 2 appears in the text box.
  15. Click the right arrow (>) to move to the next page of records. The error message mentioned in the "Symptoms" section appears.

↑ Back to the top


References

For more information about creating and populating a DataGrid control, visit the following Microsoft Web site: For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
318131 HOW TO: Page Through a Query Result for Better Performance

↑ Back to the top


Keywords: kbwebforms, kbweb, kberrmsg, kbevent, kbdataadapter, kbdatabinding, kbservercontrols, kbprb, KB813832

↑ Back to the top

Article Info
Article ID : 813832
Revision : 9
Created on : 4/30/2003
Published on : 4/30/2003
Exists online : False
Views : 516