Search code examples
c#asp.netcheckboxgridviewpagination

Gridview Paging checkbox not assigning properly


I have data in my gridview and a pagesize = 2. Also each row in gridview has a checbox for approve/reject.

If I checked 2 rows from 1st page and 2 rows from 2nd page, it only approves the last two page checked from the 2nd page. Why this happens I don't know. I want all the 4 records to get approved.

Below is my code which I wrote:

ASPX

<asp:GridView ID="grdDisplayCMMData" runat="server" 
     AutoGenerateColumns="false" Width="100%" ShowHeaderWhenEmpty="true" 
     CssClass="heavyTable table" EmptyDataText="No records to display"
     AllowPaging="true" PageSize="2" 
     OnPageIndexChanging="grdDisplayCMMData_PageIndexChanging">
    <Columns>                    
                <asp:TemplateField HeaderText="ID" Visible="false">
                    <ItemTemplate>
                        <asp:Label ID="lblID_CMM" runat="server" Text='<%#Eval("ID") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="SAP ID">
                    <ItemTemplate>
                        <asp:Label ID="lblSAP_ID_CMM" runat="server" Text='<%#Eval("SAP_ID") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="ID OD CHANGE">
                    <ItemTemplate>
                        <asp:Label ID="lblID_OD_COUNTCHANGE_CMM" runat="server" Text='<%#Eval("ID_OD_COUNTCHANGE") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="ID OD CHANGE DATE">
                    <ItemTemplate>
                        <asp:Label ID="lblID_OD_CHANGEDDATE_CMM" runat="server" Text='<%#Eval("ID_OD_CHANGEDDATE") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="RRH COUNT CHANGE">
                    <ItemTemplate>
                        <asp:Label ID="lblRRH_COUNTCHANGE_CMM" runat="server" Text='<%#Eval("RRH_COUNTCHANGE") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="RRH COUNT CHANGE DATE">
                    <ItemTemplate>
                        <asp:Label ID="lblRRH_CHANGEDDATE_CMM" runat="server" Text='<%#Eval("RRH_CHANGEDDATE") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="TENANCY COUNT CHANGE">
                    <ItemTemplate>
                        <asp:Label ID="lblTENANCY_COUNTCHANGE_CMM" runat="server" Text='<%#Eval("TENANCY_COUNTCHANGE") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="TENANCY COUNT CHANGE DATE">
                    <ItemTemplate>
                        <asp:Label ID="lblTENANCY_CHANGEDDATE_CMM" runat="server" Text='<%#Eval("TENANCY_CHANGEDDATE") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="STATUS">
                    <ItemTemplate>
                        <asp:Label ID="lblSTATUS_CMM" runat="server" Text='<%#Eval("STATUS") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="CREATED BY" Visible="false">
                    <ItemTemplate>
                        <asp:Label ID="lblCREATEDBY_CMM" runat="server" Text='<%#Eval("CREATED_BY") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Approve/Reject">
                    <ItemTemplate>
                        <asp:CheckBox ID="chkApprRejCMM" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
    </Columns>                
</asp:GridView>

C# code:

protected void btnApproveCMM_Click(object sender, EventArgs e)
{
    try
    {
            bool flgCMM = false;
            IPColoFields ObjIPColoFields = new App_Code.IPColoFields();
            List<IPColoBilling_BKP.App_Code.UMS.UMSGroupDetails> UMSGroupDetails = (List<IPColoBilling_BKP.App_Code.UMS.UMSGroupDetails>)Session["lstUMSGroupDetails"];

            Session["lstUMSGroupDetails"] = UMSGroupDetails;
            string strApprove = "";

            foreach (GridViewRow gvrow in grdDisplayCMMData.Rows)
            {
                var checkbox = gvrow.FindControl("chkApprRejCMM") as CheckBox;

                if (checkbox.Checked)
                {
                    flgCMM = true;

                    int Id = Convert.ToInt32((grdDisplayCMMData.Rows[gvrow.RowIndex].FindControl("lblID_CMM") as Label).Text);

                    ObjIPColoFields.Unique_Id = Id;
                    ObjIPColoFields.UMS_GRP_BY_ID = intCurrentGrpId;
                    ObjIPColoFields.UMS_GRP_BY_NAME = strCurrentGrp;
                    ObjIPColoFields.UMS_GRP_TO_ID = UMSGroupDetails[1].GroupID;
                    ObjIPColoFields.UMS_GRP_TO_NAME = UMSGroupDetails[1].GroupName;
                    ObjIPColoFields.FCA_STATUS = "1";
                    ObjIPColoFields.LAST_UPDATED_BY = lblUserName.Text;
                    strApprove = CommonDB.Approve_IPCOLO_CMMLevel(ObjIPColoFields);
                }
            }

            BindCMMData();
            if (flgCMM == false)
            {
                ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Please check atleast one row'); window.location ='IpColoDefault.aspx';", true);
            }
            else
            {
                ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Record Approved successfully'); window.location ='IpColoDefault.aspx';", true);

            }

    }
    catch (Exception ex)
    {
        string strErrorMsg = ex.Message.ToString() + " " + "StackTrace :" + ex.StackTrace.ToString();
        CommonDB.WriteLog("ERROR:" + strErrorMsg, ConfigurationManager.AppSettings["IPCOLO_LOG"].ToString());
    }
}

Also see the paging code

protected void grdDisplayCMMData_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
        try
        {
            BindCMMData();
            grdDisplayCMMData.PageIndex = e.NewPageIndex;
            grdDisplayCMMData.DataBind();
        }
        catch (Exception ex)
        {
            string strErrorMsg = ex.Message.ToString() + " " + "StackTrace :" + ex.StackTrace.ToString();
            CommonDB.WriteLog("ERROR:" + strErrorMsg, ConfigurationManager.AppSettings["IPCOLO_LOG"].ToString());
        }
}

Solution

  • Well, I can think of 2 ways on how you can fix the problem.

    • Change your on page event to show / hide items.

      Default grid view paging event fires a postback and rebinds the grid therefore, you can't access checkboxes on a previous page, they just "dissapear". Now, you could solve this, by loading the full grid and then setting the visibility of the items not in your defined page rage to invisible. But this becomes very taxing with huge data and I wouldn't recommend this solution.

    • The second solution would be to save the checkboxes state, in lets say a ViewState

      This way, you should implement an OnCheckedChanged event for your checbox which would add / remove itself from the viewstate of checked indexes. Now you would also have to implement an OnItemDataBound event to render the checkbox state from your viewstate. The last step would be in your button click to loop over the viewstate and perform your logic on each item.

      <asp:GridView ID="grdDisplayCMMData" runat="server" 
          AutoGenerateColumns="false" Width="100%" ShowHeaderWhenEmpty="true" 
          CssClass="heavyTable table" EmptyDataText="No records to display"
          AllowPaging="true" PageSize="2" 
          OnPageIndexChanging="grdDisplayCMMData_PageIndexChanging">
          OnItemDataBound="grdDisplayCMMData_OnItemDataBound"
          <Columns>
              <asp:TemplateField HeaderText="Approve/Reject">
                  <ItemTemplate>
                      <asp:CheckBox ID="chkApprRejCMM" runat="server" OnCheckedChange="chkApprRejCMM_OnCheckedChanged" />
                  </ItemTemplate>
              </asp:TemplateField>
          </Columns>
      </asp:GridView>
      
      protected void chkApprRejCMM_OnCheckedChanged(object sender, EventArgs e)
      {
          if(ViewState["CheckedCheckboxes"] != null)
          {
              var CheckedCheckboxes = (List<int>)ViewState["CheckedCheckboxes"];
              var checkbox = (CheckBox)sender;
              var idLabel = (TextBox)checkbox.BindingContainer.FindControl("lblID_CMM");
              if(idLabel != null && !string.IsNullOrEmpty(idLabel.Text))
              {
                  if(checkbox.Checked)
                  {
                      if(!CheckedCheckboxes.Contains(Convert.ToInt32(idLabel.Text)))
                          CheckedCheckboxes.Add(Convert.ToInt32(idLabel.Text));
                 }
                  else
                  {
                      if(CheckedCheckboxes.Contains(Convert.ToInt32(idLabel.Text)))
                          CheckedCheckboxes.Remove(Convert.ToInt32(idLabel.Text))
                  }
              }
              ViewState["CheckedCheckboxes"] = CheckedCheckboxes; 
          }
      }
      
      protected void grdDisplayCMMData_OnItemDataBound(object sender, GridViewEventArgs e)
      {
          if (e.Row.RowType == DataControlRowType.DataRow)
          { 
              if(ViewState["CheckedCheckboxes"] != null)
              {
                  var CheckedCheckboxes = (List<int>)ViewState["CheckedCheckboxes"];
                  var checkbox = (CheckBox)e.Row.FindControl("lchkApprRejCMM");
                  var idLabel = (TextBox)e.Row.FindControl("lblID_CMM");
                  if(idLabel != null && checkbox != null && !string.IsNullOrEmpty(idLabel.Text))
                  {
                         if(CheckedCheckboxes.Contains(Convert.ToInt32(idLabel.Text)))
                          checbox.Checked = true;
                      else
                          checbox.Checked = false;
                  }
              }
          }
      }
      
      protected void YourButtonClick(object sender, EventArgs e)
      {
          if(ViewState["CheckedCheckboxes"] != null)
          {
              var CheckedCheckboxes = (List<int>)ViewState["CheckedCheckboxes"];
              foreach (var id in CheckedCheckboxes)
              {
                 //perform logic with id
              }
          }
      }
      

    EDIT 1: Some mistakes I left out by writing the code without the use of an IDE