1

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] + ",";
                        }
                    }
                }
            }
        }
    }

2 Answers 2

1

Your approach is right, however you need to consider few more things:

  1. You have to loop through the Repeater's items and find the Panel in each item.

  2. You have to find the GridView inside the Panel, not in the Repeater.

  3. 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!

Sign up to request clarification or add additional context in comments.

9 Comments

I have added these codes to test whether the prodID getting is correct or not (check the edited portion again, sorry). However, no matter I checked on which products, it just keep returning me a weird value as in I have no idea where the value comes from.
Oh ya, I forgot to concatenate the prodID and that's why it keeps returning one value instead of a list. Thanks a lot!
However, it keeps looping the record over and over again. Let's say I got product 1,2,6,7 checked. It returns me 1,1,2,1,2,6,1,2,6,7. I guess at the first check, it returns me 1. At the second check, it returns me 1,2 and so on. I guess because I am using repeater and collapsible panel extender and that's why it keep looping over and over again. Is there any ways to fix this?
@Gwen - I think your test has some issues, you should not loop through the list inside loops. I have added test code for this which worked for me. Can you please check?
@afzaluluh Oh I see. I put the for-loop at the wrong place. So basically if I wanted to loop thru the list to get product details of each prodID, I should replace the lblTest.Text with for-loop?
|
0

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);

        }
     }

    }

10 Comments

But how I know whether the checkbox column is checked? as In I should move all the codes inside my lbnConfirm_onClick into here?
i have edited my answer...!! to help u know how to use datakeys to get values
But at the gvProduct, it told not does not contain a definition of 'gvProduct' and no extension method accepting first argument type which I encountered the same thing using my code above. Also, I don't have button field in grid view so I can't use the command name. It just simply checkbox coulmn
u must select the event RowDatabound from the Gridview properties
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.