Monday, February 2, 2009

Maintaining State of CheckBox while Paging in GridView

Submit this story to DotNetKicks

The Logic

We are storing the primary keys of the checkboxes that are checked into a List 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.
Heres the sample code.

The ASPX

<asp:LinkButton ID="btnSelectAllPage" runat="server" 
            CommandName="SelectAllPage" 
            Text="Select All Pages"
            OnCommand="SelectDeselectAllPages" />|
<asp:LinkButton ID="btnDeselectAllPage" runat="server" 
            CommandName="DeselectAllPage" 
            Text="Deselect All Pages"
            OnCommand="SelectDeselectAllPages" />|
<asp:LinkButton ID="btnSelectAll" runat="server" 
            CommandName="SelectAll" 
            Text="Select Page"
            OnCommand="SelectDeselect" />|
<asp:LinkButton ID="btnDeselectAll" runat="server" 
            CommandName="DeselectAll" 
            Text="Deselect Page"
            OnCommand="SelectDeselect" />

<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:SqlDataSource ID="sdsProducts" runat="server"
                ConnectionString='<%$ ConnectionStrings:NorthwindConnectionString %>'
                SelectCommand="SELECT * FROM Products">
</asp:SqlDataSource>



The 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>;
    }
}

protected void SelectDeselect(object sender, CommandEventArgs e)
{
    foreach (GridViewRow gvr in gvProducts.Rows)
    {
        CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
        if (chkSelect != null)
        {
            chkSelect.Checked = e.CommandName.Equals("SelectAll");
        }
    }
}

protected void SelectDeselectAllPages(object sender, CommandEventArgs e)
{
    DataSourceSelectArguments dssa = new DataSourceSelectArguments();
    dssa.AddSupportedCapabilities(DataSourceCapabilities.RetrieveTotalRowCount);
    dssa.RetrieveTotalRowCount = true;
    DataView dv = (DataView)sdsProducts.Select(dssa);
    foreach (DataRow dr in dv.Table.Rows)
    {

        int productID = Convert.ToInt32(dr.ItemArray[0]);//ItemArray[0] cos ProductID is in the first column
        if (e.CommandName.Equals("SelectAllPage") && !this.ProductIDs.Contains(productID))
        {
            this.ProductIDs.Add(productID);
        }
        if (e.CommandName.Equals("DeselectAllPage") && this.ProductIDs.Contains(productID))
        {
            this.ProductIDs.Remove(productID);
        }
    }
    foreach (GridViewRow gvr in gvProducts.Rows)
    {
        CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
        if (chkSelect != null)
        {
            chkSelect.Checked = e.CommandName.Equals("SelectAllPage");
        }
    }
}

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

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

As an extra enhancement, we are also giving provision for selecting, deselecting both page and the whole rows in every page also here.

P.S: We are using Northwind Sample DataBase by Microsoft, so if you dont have it download it.

Courtesy: A wonderful post by Ed Bruck at forums.asp.net

Related Posts :



0 comments on "Maintaining State of CheckBox while Paging in GridView"

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

Post a Comment