Tuesday, December 7, 2010

Maintaining CheckBox State of multiple GridViews


Almost two years back, I did a post on Maintaining State of Checkbox while Paging in Gridview

This post is an extension to it. this is the code to maintain CheckBox states of multiple gridviews in a page.

The logic is simple. We are storing the primary keys of the checkboxes that are checked into a List<T> where T = data type of the primary key. This is done at PageIndexChanging before we change the page index and re-bind the GridView. And at RowDataBound we are checking whether the DataKeyName(primary key) of each row is in the List. If present , we mark the CheckBox as checked.

At ASPX

<asp:GridView ID="gvProducts" runat="server" 
            AllowPaging="True" 
            AutoGenerateColumns="False"
            DataKeyNames="ProductID"
            OnPageIndexChanging="gvProducts_PageIndexChanging" 
            OnRowDataBound="gvProducts_RowDataBound">
    <Columns>
        <asp:TemplateField HeaderText="Select">
            <ItemTemplate>
                <asp:CheckBox ID="chkSelect" runat="server" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID" InsertVisible="False"
        ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />
    </Columns>
</asp:GridView>
<asp:GridView ID="gvCustomers" runat="server" 
            AllowPaging="True" 
            AutoGenerateColumns="False"
            DataKeyNames="CustomerID"
            OnPageIndexChanging="gvCustomers_PageIndexChanging" 
            OnRowDataBound="gvCustomers_RowDataBound">
    <Columns>
        <asp:TemplateField HeaderText="Select">
            <ItemTemplate>
                <asp:CheckBox ID="chkSelect" runat="server" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CustomerID" HeaderText="ID" InsertVisible="False" />
        <asp:BoundField DataField="CompanyName" HeaderText="CompanyName"  />
    </Columns>
</asp:GridView>

At ASPX.CS

private List<int> ProductIDs
{
    get
    {
        if (this.ViewState["ProductIDs"] == null)
        {
            this.ViewState["ProductIDs"] = new List<int>();
        }
        return this.ViewState["ProductIDs"] as List<int>;
    }
}

private List<string> CustomerIDs
{
    get
    {
        if (this.ViewState["CustomerIDs"] == null)
        {
            this.ViewState["CustomerIDs"] = new List<string>();
        }
        return this.ViewState["CustomerIDs"] as List<string>;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        BindGrid(gvProducts, "Products");
        BindGrid(gvCustomers, "Customers");
    }
}

protected void gvProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    foreach (GridViewRow gvr in gvProducts.Rows)
    {
        CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
        if (chkSelect != null)
        {
            int productID = Convert.ToInt32(gvProducts.DataKeys[gvr.RowIndex]["ProductID"]);
            if (chkSelect.Checked && !this.ProductIDs.Contains(productID))
            {
                this.ProductIDs.Add(productID);
            }
            else if (!chkSelect.Checked && this.ProductIDs.Contains(productID))
            {
                this.ProductIDs.Remove(productID);
            }
        }
    }
    gvProducts.PageIndex = e.NewPageIndex;
    BindGrid(gvProducts, "Products");
}

protected void gvProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    GridViewRow gvr = e.Row;
    if (gvr.RowType == DataControlRowType.DataRow)
    {
        CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
        if (chkSelect != null)
        {
            int productID = Convert.ToInt32(gvProducts.DataKeys[gvr.RowIndex]["ProductID"]);
            chkSelect.Checked = this.ProductIDs.Contains(productID);
        }
    }
}

protected void gvCustomers_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    foreach (GridViewRow gvr in gvCustomers.Rows)
    {
        CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
        if (chkSelect != null)
        {
            string customerID = gvCustomers.DataKeys[gvr.RowIndex]["CustomerID"].ToString();
            if (chkSelect.Checked && !this.CustomerIDs.Contains(customerID))
            {
                this.CustomerIDs.Add(customerID);
            }
            else if (!chkSelect.Checked && this.CustomerIDs.Contains(customerID))
            {
                this.CustomerIDs.Remove(customerID);
            }
        }
    }
    gvCustomers.PageIndex = e.NewPageIndex;
    BindGrid(gvCustomers, "Customers");
}

protected void gvCustomers_RowDataBound(object sender, GridViewRowEventArgs e)
{
    GridViewRow gvr = e.Row;
    if (gvr.RowType == DataControlRowType.DataRow)
    {
        CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
        if (chkSelect != null)
        {
            string customerID = gvCustomers.DataKeys[gvr.RowIndex]["CustomerID"].ToString();
            chkSelect.Checked = this.CustomerIDs.Contains(customerID);
        }
    }
}

private DataTable PopulateData(string tableName)
{
    DataTable dt = new DataTable();
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString))
    {
        string sql = String.Format("SELECT * FROM {0}", tableName);
        using (SqlDataAdapter adap = new SqlDataAdapter(sql, conn))
        {
            adap.Fill(dt);
        }
    }
    return dt;
}

private void BindGrid(GridView gvTemp, string tableName)
{
    gvTemp.DataSource = PopulateData(tableName);
    gvTemp.DataBind();
}

Happy Coding!

P.S: Database in use is Northwind Sample Database.

Related Posts :



0 comments on "Maintaining CheckBox State of multiple GridViews"

Add your comment. Please don't spam!
Subscribe in a Reader

Post a Comment