I have this template field
<asp:TemplateField ItemStyle-Width="40px">
<HeaderTemplate>
<asp:CheckBox ID="chkboxSelectAll" runat="server" AutoPostBack="true" OnCheckedChanged="chkboxSelectAll_CheckedChanged" />
</HeaderTemplate>
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" />
<ItemTemplate>
<asp:CheckBox ID="chkEmp" runat="server"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
In the code-behind I have this code:
protected void chkboxSelectAll_CheckedChanged(object sender, EventArgs e)
{
CheckBox ChkBoxHeader = (CheckBox)grdGeral.HeaderRow.FindControl("chkboxSelectAll");
foreach (GridViewRow row in grdGeral.Rows)
{
CheckBox ChkBoxRows = (CheckBox)row.FindControl("chkEmp");
if (ChkBoxHeader.Checked == true)
{
ChkBoxRows.Checked = true;
}
else
{
ChkBoxRows.Checked = false;
}
}
}
protected void btnLista_Click(object sender, EventArgs e)
{
string strEmailTotal = "";
string strEmail = "";
foreach (GridViewRow row in grdGeral.Rows)
{
CheckBox chkBx = (CheckBox)grdGeral.FindControl("chkEmp");
if (chkBx != null)
{
if (chkBx.Checked)
{
strEmail = ((Label)grdGeral.FindControl("lblEmail")).Text;
strEmailTotal = strEmailTotal + "," + strEmail;
}
}
}
lblMail.Text = strEmailTotal ;
}
I always get a null value for the checkbox, even if I set the default value to "true" in the templatefield. Can anyone help me with this?
Thank you
In your btnLista_Click event you should use row instead grdGeral:
CheckBox chkBx = (CheckBox)row.FindControl("chkEmp");
And below this the same:
strEmail = ((Label)row.FindControl("lblEmail")).Text;
try this solution.
foreach (GridViewRow row in grdGeral.Rows)
{
CheckBox chkBx = row.FindControl("chkEmp") as CheckBox ;
}
Related
I am creating dynamic Template Fields for my gridview:
<asp:GridView ID="grdData" runat="server" DataKeyNames = "ID" AutoGenerateColumns="false" OnRowDataBound="grdData_RowDataBound">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkAll" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="editbtn" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
the code to add templateField is below:
private void BindGridView(DataTable dtData)
{
foreach (DataColumn item in dtData.Columns)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = item.ToString();
grdData.Columns.Add(tfield);
}
grdData.DataSource = dtData;
ViewState["dtDataTable"] = dtData;
grdData.DataBind();
}
and in row databound I am adding textbox and label to the templatefield:
protected void grdData_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataTable dtData = (DataTable)ViewState["dtDataTable"];
if (e.Row.RowType == DataControlRowType.DataRow)
{
int i = 1;
foreach (DataColumn item in dtData.Columns )
{
TextBox txtBox = new TextBox();
txtBox.ID = "txt"+item.ToString();
txtBox.Text = (e.Row.DataItem as DataRowView).Row[item.ToString()].ToString();
txtBox.Visible = false;
e.Row.Cells[i].Controls.Add(txtBox);
Label lblBox = new Label();
lblBox.ID = "lbl" + item.ToString();
lblBox.Text = (e.Row.DataItem as DataRowView).Row[item.ToString()].ToString();
e.Row.Cells[i].Controls.Add(lblBox);
i++;
}
}
}
Everything is working good so far,The grid is getting created and the values are getting populated ,but when i am calling below method and try to access the gridview control ,its throwing object reference error:
protected void OnCheckedChanged(object sender, EventArgs e)
{
bool isUpdateVisible = false;
CheckBox chk = (sender as CheckBox);
if (chk.ID == "chkAll")
{
foreach (GridViewRow row in grdData.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked = chk.Checked;
}
}
}
CheckBox chkAll = (grdData.HeaderRow.FindControl("chkAll") as CheckBox);
chkAll.Checked = true;
foreach (GridViewRow row in grdData.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
bool isChecked = row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked;
for (int i = 1; i < row.Cells.Count; i++)
{
Label test= row.FindControl("lblName") as Label;//this is coming null
Below code lines are throwing object reference error as they are not able to find control
row.Cells[i].Controls.OfType<Label>().FirstOrDefault().Visible = !isChecked;//this line throwing object reference error
if (row.Cells[i].Controls.OfType<TextBox>().ToList().Count > 0)
{
row.Cells[i].Controls.OfType<TextBox>().FirstOrDefault().Visible = isChecked;
}
if (row.Cells[i].Controls.OfType<DropDownList>().ToList().Count > 0)
{
row.Cells[i].Controls.OfType<DropDownList>().FirstOrDefault().Visible = isChecked;
}
if (isChecked && !isUpdateVisible)
{
isUpdateVisible = true;
}
if (!isChecked)
{
chkAll.Checked = false;
}
}
}
}
btnUpdate.Visible = isUpdateVisible;
}
Edit:
I tried reinistialising the controls in preinit event but still no luck:
protected void Page_PreInit(object sender, EventArgs e)
{
if (ViewState["gridData"] != null)
{
BindGridView((DataTable)ViewState["gridData"]);
}
}
What I am doing wrong?
I recreated the dynamic gridview Controls in OnRowCreated as this event gets called in every postback instead of onRowDataBound Event and it worked like charm.
protected void Gridproducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hp = new HyperLink();
hp = (HyperLink)e.Row.FindControl("linkSelectprd");
var Pid = DataBinder.Eval(e.Row.DataItem, "product_id").ToString();
var Catid = Request.QueryString["Cid"].ToString();
hp.NavigateUrl = "Sales.aspx?Cid="+Catid+"&"+"Pid="+Pid;
if (!IsPostBack && Request.QueryString["Pid"] != null)
{
this is the variable in which the value of quantity increments
int i=0;
lbltotalquantity.Text = i.ToString() + 1;
}
}
}
}
I use LinkButtons inside a Grid template. I want to be able to raise events when clicking the LinkButtons the value of lable is incremented on + link and decrementd on - link button as lable contains the quantity of Products added to invoice. How can I accomplish this?
I believe this is what you want....
You don't do the increment in RowDataBound because RowDataBound trigger when you are binding the GridView
.aspx
<asp:ScriptManager ID="sm" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="up" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Product">
<ItemTemplate>
<asp:Label ID="lblProduct" runat="server" Text='<%# Eval("Product") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:Label ID="lblQuantity" runat="server" Text="0"></asp:Label>
<asp:LinkButton ID="lbtnPlus" runat="server" Text="+" OnClick="lbtnPlus_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtnMinus" runat="server" Text="-" OnClick="lbtnMinus_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="gv" />
</Triggers>
</asp:UpdatePanel>
.cs
protected void Page_Load(object sender, EventArgs e)
{
// Check
if (!IsPostBack)
{
// Variable
string[] product = { "Dell", "Asus", "Acer", "Toshiba", "Fujishu", "VAIO" };
DataTable dt = new DataTable();
dt.Columns.Add("Product");
for (int i = 0; i < product.Length; i++)
dt.Rows.Add(product[i]);
gv.DataSource = dt;
gv.DataBind();
// Dispose
dt.Dispose();
}
}
private void DoTheMath(GridViewRow row, bool isAdd)
{
// Variable
bool isNumber = false;
int currentValue = 0;
// Find Control
Label lblQuantity = row.FindControl("lblQuantity") as Label;
// Check
if (lblQuantity != null)
{
// Check
if (lblQuantity.Text.Trim() != string.Empty)
{
isNumber = int.TryParse(lblQuantity.Text.Trim(), out currentValue);
// Check
if (isNumber)
{
// Is Add
if (isAdd)
currentValue++;
else
{
// Check cannot be less than 0
if (currentValue > 0)
currentValue--;
}
}
// Set to TextBox
lblQuantity.Text = currentValue.ToString();
}
}
}
protected void lbtnPlus_Click(object sender, EventArgs e)
{
// Get
LinkButton lbtn = sender as LinkButton;
GridViewRow row = lbtn.NamingContainer as GridViewRow;
DoTheMath(row, true);
}
protected void lbtnMinus_Click(object sender, EventArgs e)
{
// Get
LinkButton lbtn = sender as LinkButton;
GridViewRow row = lbtn.NamingContainer as GridViewRow;
DoTheMath(row, false);
}
This is my code behind code. I want to populate the DropDownList once the user clicked edit but the DropDownList I'm getting is null. Why?
protected void SupportSchedule_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "EditRow")
{
int rowIndex = ((GridViewRow)((ImageButton) e.CommandSource).NamingContainer).RowIndex;
GridViewRow row = (GridViewRow)(((ImageButton) e.CommandSource).NamingContainer);
SupportScheduleTable.EditIndex = rowIndex;
shift.Enabled = true;
resourcedate.Enabled = true;
ListItemCollection c = db.fillList();
DropDownList ddl1 = row.FindControl("ddlshiftmanager") as DropDownList;
DropDownList ddl2 = row.FindControl("ddldispatcherone") as DropDownList;
DropDownList ddl3 = row.FindControl("ddldispatchertwo") as DropDownList;
if (c != null && ddl1 != null)
{
ddl1.DataSource = c;
ddl2.DataSource = c;
ddl3.DataSource = c;
ddl1.DataBind();
ddl2.DataBind();
ddl3.DataBind();
}
getSupportSchedule();
}
else if (e.CommandName == "CancelUpdate")
{
//some codes here
} else if (e.CommandName == "UpdateRow")
{
//some codes here
}
}
//asp code
<asp:GridView ID="SupportScheduleTable" AutoGenerateColumns="False" Width="100%" runat="server" OnRowCommand="SupportSchedule_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Shift Manager">
<EditItemTemplate>
<asp:DropDownList ID="ddlshiftmanager" runat="server" Width="99%"></asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("shift_manager") %>'></asp:Label>
</ItemTemplate>
<HeaderStyle Width="32%" />
</asp:TemplateField>
<asp:TemplateField ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="lbEdit" CssClass="btn" ImageUrl="~/Files/edit.png" CommandArgument='<%# Eval("support_schedule_id") %>' CommandName="EditRow" runat="server"></asp:ImageButton>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="lbUpdate" CommandArgument='<%# Eval("support_schedule_id") %>' CommandName="UpdateRow" runat="server">Update</asp:LinkButton>
<asp:LinkButton ID="lbCancel" CommandArgument='<%# Eval("support_schedule_id") %>' CommandName="CancelUpdate" runat="server" CausesValidation="false">Cancel</asp:LinkButton>
</EditItemTemplate>
<HeaderStyle Width="2%" />
</asp:TemplateField>
//two dropdownlists before image button
</Columns>
</GridView>
I just added the ImageButton here in the recent update but this is my original code that doesn't work.
I used a SqlDataSource instead of adding the list items from the back
and this is what I used to get the selected value of the DropDownList.
else if (e.CommandName == "UpdateRow")
{
int rowIndex = ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer).RowIndex;
DropDownList ddlshift = (DropDownList)SupportScheduleTable.Rows[rowIndex].FindControl("ddlshiftmanager");
DropDownList ddlone = (DropDownList)SupportScheduleTable.Rows[rowIndex].FindControl("ddldispatcherone");
DropDownList ddltwo = (DropDownList)SupportScheduleTable.Rows[rowIndex].FindControl("ddldispatchertwo");
string manager = ddlshift.SelectedValue;
string one = ddlone.SelectedValue;
string two = ddltwo.SelectedValue;
int supportID = Convert.ToInt32(e.CommandArgument);
String sh = shift.Text;
String date = resourcedate.Text;
db.updateSS(supportID, sh, manager, one, two,date);
SupportScheduleTable.EditIndex = -1;
shift.Enabled = false;
resourcedate.Enabled = false;
getSupportSchedule();
}
Your answer is a correct way to handle the issue you are seeing. But, in case you didn't figure out the actual cause...
The ImageButton you click is in your ItemTemplate. The DropDownList you want to bind is in your EditItemTemplate. lbEdit exists when you are not in edit mode but ddlshiftmanager only exists when you are.
So, the fix is to put the GridView in edit mode. Notice that this is something you actually already started to do. You need to set the EditIndex, re-bind the GridView, then get the row again. You'll then have the row in edit mode. This row should now contain ddlshiftmanager.
protected void SupportSchedule_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "EditRow")
{
int rowIndex = ((GridViewRow)((ImageButton) e.CommandSource).NamingContainer).RowIndex;
// Set the index to edit
SupportScheduleTable.EditIndex = rowIndex;
// Re-bind the GridView to put it in edit mode
SupportScheduleTable.DataSource = /* your data source */
SupportScheduleTable.DataBind();
// Get the row at the index. The row will be the
// row reflected in edit mode.
GridViewRow editRow = SupportScheduleTable.Rows[rowIndex];
// Find your DropDownLists in this edit row
DropDownList ddl1 = editRow.FindControl("ddlshiftmanager") as DropDownList;
DropDownList ddl2 = editRow.FindControl("ddldispatcherone") as DropDownList;
DropDownList ddl3 = editRow.FindControl("ddldispatchertwo") as DropDownList;
shift.Enabled = true;
resourcedate.Enabled = true;
ListItemCollection c = db.fillList();
if (c != null && ddl1 != null)
{
ddl1.DataSource = c;
ddl2.DataSource = c;
ddl3.DataSource = c;
ddl1.DataBind();
ddl2.DataBind();
ddl3.DataBind();
}
getSupportSchedule();
}
// Everything else...
}
Please help me with following, just something weird is going on.
I have a gridview with paging where the first column is filled with checkboxes.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="..." DataKeyNames="EventID" EnableViewState="false"
GridLines="None" AllowSorting="True"
AllowPaging="True" Width="100%"
onpageindexchanging="GridView1_PageIndexChanging"
onprerender="GridView1_PreRender">
<HeaderStyle Wrap="false" />
<Columns>
<asp:TemplateField HeaderStyle-HorizontalAlign="Left">
<HeaderTemplate>
<asp:CheckBox ID="SelectAllEvs" runat="server" EnableViewState="false" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="EventSelector" runat="server" EnableViewState="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ... >
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:BoundField ... >
</asp:BoundField>
<asp:BoundField ... >
</asp:BoundField>
</Columns>
</asp:GridView>
CodeBehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["PageIndex"] != null)
{
GridView1.PageIndex = Convert.ToInt32(Session["PageIndex"]);
}
}
}
protected void GridView1_PreRender(object sender, EventArgs e)
{
// loading checkbox values from the session collection
GridView gv = (GridView)sender;
LoadCheckboxState(gv);
Session["PageIndex"] = gv.PageIndex;
}
private void LoadCheckboxState(GridView gv)
{
for (int i = 0; i < gv.Rows.Count; i++)
{
var chkBox = GridView1.Rows[i].FindControl("EventSelector") as CheckBox;
int id = gv.PageIndex * gv.PageSize + i;
if (SelectedIndexes.Contains(id))
{
chkBox.Checked = true;
}
else
{
chkBox.Checked = false;
}
}
}
private List<int> SelectedIndexes
{
get
{
if(Session["selectedRows"] == null)
{
Session["selectedRows"] = new List<int>();
}
return (List<int>)Session["selectedRows"];
}
}
private void SaveCheckboxState(GridView gv)
{
for (int i = 0; i < GridView1.Rows.Count; i++)
{
var chkBox = GridView1.Rows[i].FindControl("EventSelector") as CheckBox;
int id = gv.PageIndex * gv.PageSize + i;
if (chkBox.Checked)
{
//see if we have an id added already
if (!SelectedIndexes.Contains(id))
{
SelectedIndexes.Add(id);
}
}
else
{
if (SelectedIndexes.Contains(id))
{
SelectedIndexes.Remove(id);
}
}
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
// saving current page checkbox values to the session collection
GridView gv = (GridView)sender;
SaveCheckboxState(gv);
GridView1.PageIndex = e.NewPageIndex;
}
When I first get to my page I check some checkboxes and then press F5. Apparently after pressing it I dont have any values in SelectediIndexes and all unselected checkboxes must be checked = false on the PreRender stage but they appear checked after all this. And the problem of the same nature: I checked some on the first page; went to the second page (currently having 2 indexes in the SelectedValues) and after pressing F5 the same I have checked the same checkboxes as on the first page, though they mustn't. I'm absolutely confused with this. How can I fix this? Thanx for any help.
I've found the reason to that strange behavior. I'm using Firrefox. And one of the features of this browser is saving state of some fields when refreshing the page. If you want to refresh a page fully you should refresh it with pressed shift button. Tested in Google Chrome - works just fine.
I am trying to do when the checkbox column in my gridview is marked, I get the row index. My gridview is in a repeater and when I setup the gridview, I put a DataKeyNames:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<asp:Panel ID="pBody1" runat="server" CssClass="cpBody">
<asp:Label ID="lblBodyText1" runat="server" />
<!-- Grid view to show products based on each category -->
<asp:GridView ID="gvProduct" runat="server" AutoGenerateColumns="False" Width="998px" CellPadding="4" ForeColor="#333333" GridLines="None" ShowHeader="False" DataKeyNames="id">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:TemplateField ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="cbCheckRow" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="name" HeaderText="Name" ItemStyle-Width="600px" />
<asp:BoundField DataField="categoryName" HeaderText="Category" />
<asp:TemplateField HeaderText="Quantity" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:TextBox ID="tbQuantity" runat="server" Width="60" Text='<%# DataBinder.Eval(Container.DataItem, "inventoryQuantity") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
<asp:CollapsiblePanelExtender ID="cpe1" runat="server" TargetControlID="pBody1" CollapseControlID="pHeader1"
ExpandControlID="pHeader1" Collapsed="true" ImageControlID="imgArrows1"
CollapsedImage="~/Images/downarrow.jpg"
ExpandedImage="~/Images/uparrow.jpg" TextLabelID="lblHeaderText1" CollapsedText="Show"
ExpandedText="Hide" CollapsedSize="0"
ScrollContents="false">
</asp:CollapsiblePanelExtender>
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton ID="lbnConfirm" runat="server" class="btn dark" style="float: right" OnClick="lbnConfirm_Click">Confirm</asp:LinkButton>
When my lbnConfirm is onclick, I perform this to get the row index and store them into a list:
protected void lbnConfirm_Click(object sender, EventArgs e)
{
GridView gv = (GridView)Repeater1.FindControl("gvProduct") as GridView;
foreach (GridViewRow gr in gv.Rows)
{
CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbCheckRow");
if (cb.Checked)
{
GridViewRow row = gv.SelectedRow;
string prodID = this.gv.DataKeys[row].Value.ToString();
List<DistributionStandardPackingUnitItems> distSPUList = new List<DistributionStandardPackingUnitItems>();
//Store the prodIDs into list
}
}
}
When I run the page, it told me object reference is not set to an instance at this line:
foreach (GridViewRow gr in gv.Rows)
Also the gv of this line:
string prodID = this.gv.DataKeys[row].Value.ToString();
told me that the gv does not contain a definition of missing reference. I thought I declared at the code above?
Edited Portion:
protected void lbnConfirm_Click(object sender, EventArgs e)
{
foreach (RepeaterItem item in Repeater1.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
Panel pnl = item.FindControl("pBody1") as Panel;
GridView gv = pnl.FindControl("gvProduct") as GridView;
foreach (GridViewRow gr in gv.Rows)
{
CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbCheckRow");
if (cb.Checked)
{
string prodID = gv.DataKeys[gr.RowIndex].Value.ToString();
tempList.Add(prodID);
for (int count = 0; count < tempList.Count; count++)
{
lblTest.Text = tempList[count] + ",";
}
}
}
}
}
}
Your approach is right, however you need to consider few more things:
You have to loop through the Repeater's items and find the Panel in
each item.
You have to find the GridView inside the Panel, not in the Repeater.
You have to find the DataKey Value by RowIndex, not by row.
EDIT : To test, add a Label outside the repeater:
<asp:Label ID="lblTest" runat="server" Text=""></asp:Label>
Also change the code to display Id in the label.
After rewriting lbnConfirm_Click() method, it should look like below:
protected void lbnConfirm_Click(object sender, EventArgs e)
{
List<string> tempList = new List<string>();
foreach (RepeaterItem item in Repeater1.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
Panel pnl = item.FindControl("pBody1") as Panel;
GridView gv = pnl.FindControl("gvProduct") as GridView;
foreach (GridViewRow gr in gv.Rows)
{
CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbCheckRow");
if (cb.Checked)
{
//GridViewRow row = gv.SelectedRow;
string prodID = gv.DataKeys[gr.RowIndex].Value.ToString();
List<DistributionStandardPackingUnitItems> distSPUList = new List<DistributionStandardPackingUnitItems>();
//Store the prodIDs into list
tempList.Add(prodID);
}
}
}
}
lblTest.Text = string.Join(",", tempList);
}
The code above worked fine in my test! Only you have to be careful not to rebind the repeater at postback in Page_Load().
Hope it helps!
get the row index in the RowDataBound event :
protected void gvProduct_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.commandName=="select")
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int index = e.Row.RowIndex;
CheckBox chk = (CheckBox)e.Row.FindControl("cbCheckRow");
int code = Convert.ToInt32(this.gvProduct.DataKeys[e.Row.RowIndex].Value);
}
}
}