So I have a web site that uses a main GridView with child GridView.
I want to a copy (clone) existing row and paste it back into the main GridView.
Using my code below I obtain this error because the SProc
in MySql
that populates the child GridView don't find the expected parameter
Exception Details:
MySql.Data.MySqlClient.MySqlException:
Incorrect integer value: '' for column 'tcustomerId' at row 1
On main GridView I have set
DataKeyNames="CustomerId"
On child GridView (into gvProducts_RowDataBound
)
string CustomerId = gvProducts.DataKeys[e.Row.RowIndex].Value.ToString();
On the VS 2019 the debug the return of value in cmdCopy_Click
event it's correct
CustomerId = Convert.ToInt32(index).ToString();
Line error is 1027
Line 1025: MySqlDataAdapter adapter = new MySqlDataAdapter();
Line 1026: adapter = new MySqlDataAdapter(cmd);
Line 1027: adapter.Fill(ds);
Line 1028: cmd.Connection.Close();
Thanks for any advice.
protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.DataItem != null)
{
GridView gv_Child = (GridView)e.Row.FindControl("gv_Child");
if (gv_Child != null)
{
string CustomerId = gvProducts.DataKeys[e.Row.RowIndex].Value.ToString();
DataSet ds = new DataSet();
using (MySqlConnection cn =
new MySqlConnection(ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
{
using (MySqlCommand cmd =
new MySqlCommand("SProc", cn))
{
cmd.Connection.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("tcustomerId", customerId);
MySqlDataAdapter adapter = new MySqlDataAdapter();
adapter = new MySqlDataAdapter(cmd);
adapter.Fill(ds);
cmd.Connection.Close();
gv_Child.DataSource = ds.Tables[0];
gv_Child.DataBind();
}
}
}
}
}
}
protected void cmdCopy_Click(object sender, ImageClickEventArgs e)
{
GridViewRow gvRow = (sender as ImageButton).NamingContainer as GridViewRow;
int index = gvRow.RowIndex;
CustomerId = Convert.ToInt32(index).ToString();
HiddenField hd = gvRow.FindControl("hf") as HiddenField;
string hValue = hd.Value.ToString().Replace('.',',');
DataTable dt = RetrieveProducts();
DataRow dr = dt.NewRow();
dr["tValue"] = hValue;
dt.Rows.InsertAt(dr, index 1);
BindData();
}
CodePudding user response:
You get the gv index, and then from index, you can get the datakey (the hidden PK value) for that row. The WHOLE idea of datakeys is that you can thus get the PK row value, but NOT have to include it in the markup.
So, for that "copy", you get the index, and then to get the customerID (datakey), you use the index into the DataKeys array.
Row idex is simple the row starting at 0, then 1, then 2 for the number of rows - rowindex thus gets you the row number, and NOT the PK or datakey value.
eg like this:
GridViewRow gvRow = (sender as ImageButton).NamingContainer as GridViewRow;
int index = gvRow.RowIndex;
int CustomerId = (int)MyGrid.DataKeys[index]["CustomerID"];
Now you can replace CustomerID with whatever your datakeys setting is, but you not shared the GV markup of asp:GridView line, so we can't see.
However, I fail to see how row databound can be used, since that fires EACH time and for EACH row - and thus setting a global string customerId would make ZERO sense here. So, declare CustomerID, and use row index to get the data keys setting.
As noted, I have to guess the datakeys setting, but use whatever the name is, and by using row index, you can get that PK row value.
And row databound fires only during the binding. So your separate row click event you have will never see nor get the page scoped wide string CustomerID, since it will only have/hold the LAST row databound event, which I can't see of being ANY value or use in regards to the row click copy event . The two events have little to do with each other.