Sunday, May 20, 2012

How to keep checkbox state across over gridview pages

The GridView control is pretty a handy control and is widely used to show the records such as report when building an ASP.NET site. The more you develop with it, the more you reckon how powerful it can be while presenting data. In this article, I will show you how to keep the checkbox state across over pages on the asp.net gridview control as below.
Keeping checkbox state over gridview pages


First, we create one gridview control like this. One important thing is DataKeyNames="ProductID" that we use it later to refer the row index.
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
 Width="492px" OnPageIndexChanging="GridView1_PageIndexChanging" 
 onrowdatabound="GridView1_RowDataBound" 
 DataKeyNames="ProductID">
 <Columns>
  <asp:TemplateField HeaderText="Check">
   <ItemTemplate>
    <asp:CheckBox ID="chk" runat="server" />
   </ItemTemplate>
  </asp:TemplateField>
  <asp:BoundField DataField="ProductID" HeaderText="ProductID" />
  <asp:BoundField DataField="ProductName" HeaderText="Name" />
  <asp:BoundField DataField="UnitPrice" HeaderText="Price/Unit" DataFormatString="{0:F}" />
 </Columns>
</asp:GridView> 
In code-behind page, the code look like below. Note that there are two classes in it.
public partial class KeepCheckboxStat : System.Web.UI.Page
{
    public static List<CheckboxInfo> CheckboxSession
    {
        get { return HttpContext.Current.Session["CheckboxSession"] as List<CheckboxInfo>; }
        set { HttpContext.Current.Session["CheckboxSession"] = value; }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //Get the underlying data using EF 
            using (var container = new NorthwindEntities())
            {
                GridView1.DataSource = container.Products.ToList();
                GridView1.DataBind();
            }
        }
    }
    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        KeepCheckboxState(); //Call function to save the checkbox state
        using (var container = new NorthwindEntities())
        {
            GridView1.PageIndex = e.NewPageIndex;
            GridView1.DataSource = container.Products.ToList();
            GridView1.DataBind();
        }
    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //Get checkbox state and bind here
         if (e.Row.RowType == DataControlRowType.DataRow)
        {
            CheckBox chk = e.Row.FindControl("chk") as CheckBox;
            if (chk != null)
            {
                bool hasCheckbox = (CheckboxSession != null && CheckboxSession.Count > 0);
                if (hasCheckbox)
                {
                    DataKey dk = GridView1.DataKeys[e.Row.RowIndex];
                    foreach (var item in CheckboxSession)
                    {
                        if (item.CheckId == dk.Value.ToString())
                        {
                            chk.Checked = item.IsChecked;
                        }
                    }
                }
            }
        }
    }
    public void KeepCheckboxState()
    {
        if (CheckboxSession == null)
            CheckboxSession = new List<CheckboxInfo>();
        foreach (GridViewRow r in GridView1.Rows)
        {
            DataKey dk = GridView1.DataKeys[r.RowIndex];
            CheckBox chk = r.FindControl("chk") as CheckBox;
            if (chk.Checked)
            {
                //if CheckBox is check and new one, add here.
                if (CheckboxSession.All(x => x.CheckId != dk.Value.ToString()))
                {
                    CheckboxSession.Add(new CheckboxInfo()
                    {
                        CheckId = dk.Value.ToString(),
                        IsChecked = chk.Checked
                    });
                }
            }
            else
            {
                 //otherwise, remove it. we don't care if exist or not in array.
                 CheckboxSession.Remove(CheckboxSession.FirstOrDefault(x => x.CheckId == dk.Value.ToString()));
            }
        }
    }
}
Create one more class "CheckboxInfo" to keep CheckBox state as below.
public class CheckboxInfo
{
    public string CheckId { get; set; }
    public bool IsChecked { get; set; }
}
That's it. You'll be glad when you did.

No comments:

Post a Comment