The scenario is: i have a textbox, a button and a grid view that make up a simple webpage where you can search and edit/delete an entry. the grid view's datasource ID is set to NONE. And this is the code for populating the grid view that is found in the button1_click event:

string strConString = ConfigurationManager.ConnectionStrings["Project88_MaintenanceConnectionString"].ConnectionString;
            SqlConnection myConnect = new SqlConnection(strConString);

            string cmd = "SELECT Billcode, Telco, Access_Code, Tariff, RS, Rev_Share, TC, SD, Billcode_Desc FROM Maint_BillCode WHERE Billcode like '%'+@Billcode+'%'";
            SqlDataAdapter da = new SqlDataAdapter(cmd, myConnect);
            da.SelectCommand.Parameters.AddWithValue("@Billcode", TextBox1.Text);
            DataSet ds = new DataSet();
            da.Fill(ds, "Maint_BillCode");

            GridView1.DataSource = ds.Tables["Maint_BillCode"];
            GridView1.DataBind();

I have the following code for a method that updates a row when editing:

SqlConnection connection = new SqlConnection();   
            SqlCommand command = new SqlCommand();   
  
            GridViewRow row = GridView1.Rows[e.RowIndex];   
            connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Project88_MaintenanceConnectionString"].ConnectionString);   
            connection.Open();   
            command.Connection = connection;   
            command.CommandText = "UPDATE Maint_BillCode SET Billcode='"    
                + ((TextBox)(row.Cells[1].Controls[0])).Text + "', Telco='"    
                + ((TextBox)(row.Cells[2].Controls[0])).Text + "' , Access_Code='"    
                + ((TextBox)(row.Cells[3].Controls[0])).Text + "', Tariff='"    
                + ((TextBox)(row.Cells[4].Controls[0])).Text + "', RS='"    
                + ((TextBox)(row.Cells[5].Controls[0])).Text + "', Rev_Share='"    
                + ((TextBox)(row.Cells[6].Controls[0])).Text + "', TC='"    
                + ((TextBox)(row.Cells[7].Controls[0])).Text + "', SD='"  
                + ((TextBox)(row.Cells[8].Controls[0])).Text + "', Billcode_Desc='"    
                + ((TextBox)(row.Cells[9].Controls[0])).Text + "' WHERE DataTableID='"    
                + GridView1.DataKeys[e.RowIndex].Values["DataTableID"] + "'";   
            command.ExecuteNonQuery();   
  
            GridView1.EditIndex = -1;   
  
            bindData();   
            connection.Close();

Now, the problem is, whenever i hit the update buttong, this error appears:

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

I tried looking for solutions but none was able to answer the problem so far.

What should be done here?

There are 2 things I observerd: 1. Look at the stack trace when the code bombs. There will be line number (typically I would expect row.Cells[...] to be invalid index. Since the grid view itself is not posted, I cannot see which one it is.
Second is: one should not use

((TextBox)(row.Cells[7].Controls[0])).Text

syntax, but should use

TextBox txtChannelName = ((TextBox)gvYourGrid.Rows[e.RowIndex].FindControl("txtEWidgetName"));

If you get null pointer error, check spelling of your widget: in this case -txtEWidgetName

((TextBox)(row.Cells[7].Controls[0])).Text

This piece of code is part of a string being concatenated to form a command. So i think

TextBox txtChannelName = ((TextBox)gvYourGrid.Rows[e.RowIndex].FindControl("txtEWidgetName"));TextBox txtChannelName = ((TextBox)gvYourGrid.Rows[e.RowIndex].FindControl("txtEWidgetName"));

wont be a good solution..:) Could you please further explain what is wrong with that particular line of code? And correct, the error is pointing me back to this particular piece of code:

command.CommandText = "UPDATE Maint_BillCode SET Billcode='"+ ((TextBox)(row.Cells[1].Controls[0])).Text + "', 
Telco='" + ((TextBox)(row.Cells[2].Controls[0])).Text + "' , Access_Code='" + ((TextBox)(row.Cells[3].Controls[0])).Text + "', Tariff='" + ((TextBox)(row.Cells[4].Controls[0])).Text + "', 
RS='"+ ((TextBox)(row.Cells[5].Controls[0])).Text + "', 
ev_Share='" + ((TextBox)(row.Cells[6].Controls[0])).Text + "', 
TC='" + ((TextBox)(row.Cells[7].Controls[0])).Text + "', 
SD='"+ ((TextBox)(row.Cells[8].Controls[0])).Text + "', Billcode_Desc='"+ ((TextBox)(row.Cells[9].Controls[0])).Text + "' WHERE 
DataTableID='"+ GridView1.DataKeys[e.RowIndex].Values["DataTableID"] + "'";

I believe cells is 0 based. So...

((TextBox)(row.Cells[0].Controls[0])).Text + "', Telco='" 
+ ((TextBox)(row.Cells[1].Controls[0])).Text + "' , Access_Code='"

etc. Let me know if this fixes the problem.

One can always use temp variables. That will make life way easier to read and debug. For ex.

string chanName;
TextBox txtChannelName = ((TextBox)gvYourGrid.Rows[e.RowIndex].FindControl("txtEWidgetName"));
chanName = txtChannelName.Text;
...
//use chanName in your command

ALSO note that this command string is not recomended practice. Use SQL parameters. Simplest of the bugs will be when channel name contains single quote as part of name.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.