How to Maintain checkbox state across datagrid pages?

I am working on an eccomerce application which displays products in a datagrid.  This datagrid is paged and one of the columns is a checkbox.  The problem is I cant seem to keep the checkbox's state across datagrid pages. HELP! Here is what I have so far:

Code Behind:
---------------
Imports StoreFront.BusinessRule
Imports StoreFront.BusinessRule.Management
Imports StoreFront.SystemBase
Imports System.Text
Imports System.Web.UI.Page


Public MustInherit Class n_FeaturedProductAdmin
    Inherits System.Web.UI.UserControl

    Private Product1 As New SystemBase.NFeaturedProductBase
    Private Product2 As New SystemBase.NFeaturedProductBase
    Private Product3 As New SystemBase.NFeaturedProductBase
    Private Product4 As New SystemBase.NFeaturedProductBase
    Protected WithEvents dgProducts As System.Web.UI.WebControls.DataGrid
    Protected WithEvents btnUpdate As System.Web.UI.WebControls.Button
    Protected WithEvents lblMessage As System.Web.UI.WebControls.Label
    Protected CheckBox As System.Web.UI.WebControls.CheckBox
    Dim oSet As New SystemBase.NFeaturedProductBaseSet
    Protected WithEvents Literal1 As System.Web.UI.WebControls.Literal


#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents Product4Description As System.Web.UI.WebControls.HyperLink
    Protected WithEvents imgProduct4 As System.Web.UI.WebControls.Image
    Protected WithEvents Product3Description As System.Web.UI.WebControls.HyperLink
    Protected WithEvents imgProduct3 As System.Web.UI.WebControls.Image
    Protected WithEvents Product2Description As System.Web.UI.WebControls.HyperLink
    Protected WithEvents imgProduct2 As System.Web.UI.WebControls.Image
    Protected WithEvents Product1Description As System.Web.UI.WebControls.HyperLink
    Protected WithEvents imgProduct1 As System.Web.UI.WebControls.Image
    Protected WithEvents Label1 As System.Web.UI.WebControls.Label
    Protected WithEvents ddlCategory As System.Web.UI.WebControls.DropDownList

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region
   


    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not Page.IsPostBack Then
            ddlCategory.SelectedIndex = 0
        End If


        Session("LandingPageCategoryID") = 1
        Dim CategoryID As Integer = Session("LandingPageCategoryID")
        GetFeaturedItems(CategoryID)
        GetProductDescriptionsETC()
        If Not Page.IsPostBack Then
            GetTopLevelCategories()
        End If

        dgProducts.DataSource = CType(Session("datasource"), DataSet)
        dgProducts.DataBind()
    End Sub

    Private ReadOnly Property CompletedList() As Hashtable
        Get
            Dim hashtable As Hashtable
            If IsNothing(ViewState("Completed")) Then
                hashtable = New Hashtable
                ViewState("Completed") = hashtable
            Else
                hashtable = CType(ViewState("Completed"), Hashtable)
            End If
            Return hashtable
        End Get
    End Property




    Public Sub GetTopLevelCategories()
        Dim CategoryMGR As New BusinessRule.CCategories
        Dim oCategories As New SystemBase.CCategory
        Dim oCatArray As ArrayList
        oCatArray = CategoryMGR.ParantCategories()
        ddlCategory.DataSource = oCatArray.ToArray
        ddlCategory.DataBind()
    End Sub

    Public Function GetProductID(ByVal FeaturedProductNumber As Integer) As Integer
        Dim ProductID As Integer

        Select Case FeaturedProductNumber
            'Hard Coded for now, should get id from db
        Case 1
                ProductID = Product1.UID()

            Case 2
                ProductID = Product2.UID()
            Case 3
                ProductID = Product3.UID()
            Case 4
                ProductID = Product4.UID()

        End Select
        Return ProductID
    End Function


    Public Sub GetProductDescriptionsETC()

        Product1Description.Text = Product1.Name
        Product1Description.NavigateUrl = "http://servername/estore_tech/detail.aspx?ID=" & Product1.UID
        imgProduct1.ImageUrl = Product1.ImageSmallPath

        Product2Description.Text = Product2.Name
        Product2Description.NavigateUrl = "http://servername/estore_tech/detail.aspx?ID=" & Product2.UID
        imgProduct2.ImageUrl = Product2.ImageSmallPath

        Product3Description.Text = Product3.Name
        Product3Description.NavigateUrl = "http://servername/estore_tech/detail.aspx?ID=" & Product3.UID
        imgProduct3.ImageUrl = Product3.ImageSmallPath

        Product4Description.Text = Product4.Name
        Product4Description.NavigateUrl = "http://servername/estore_tech/detail.aspx?ID=" & Product4.UID
        imgProduct4.ImageUrl = Product4.ImageSmallPath



    End Sub

    Public Sub GetFeaturedItems(ByVal CategoryID As Integer)
        Dim FeaturedProductMGR As New BusinessRule.FeaturedProducts.NFeaturedProduct

        Dim oFeaturedItem As New SystemBase.NFeaturedProductBase
        oSet = FeaturedProductMGR.LoadFeaturedProducts(CategoryID)
        Product1 = oSet(0)
        Product2 = oSet(1)
        Product3 = oSet(2)
        Product4 = oSet(3)
    End Sub

    Private Sub ddlCategory_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ddlCategory.SelectedIndexChanged
        BindData(dgProducts.CurrentPageIndex)

    End Sub

   
    Public Sub NewPage(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgProducts.PageIndexChanged

        ProcessCheckBoxes()
        BindData(e.NewPageIndex)
        dgProducts.CurrentPageIndex = e.NewPageIndex


    End Sub
    Public Sub BindData(ByVal val As Integer)
        'Get the First Level Children for the selected Landing Page Category
        Dim CategoryMGR As New BusinessRule.CCategories
        Dim products As New FeaturedProducts.NFeaturedProduct
        Dim c As New CXMLCategoryList
        Dim oCatArray As ArrayList
        Dim x As Integer
        Dim oArray As ArrayList

        oCatArray = CategoryMGR.GetFirstLevelChildren(ddlCategory.SelectedValue)
        'Get Products by Category for each of the child categories


        For x = 0 To oCatArray.Count - 1
            c = oCatArray(x)
            oArray = CategoryMGR.GetAllProductsByCategory(c.ID) 'the productid is returned.
        Next

        'the uid in the product table is the productid from above
        ' We need to grab the product data for each item in the arraylist (each product)
        Dim ds As New DataSet


        ds.Tables.Add("Products")
        'GetProductData
        ds = products.LoadProductsForCategories(oArray)
        dgProducts.CurrentPageIndex = val
        dgProducts.DataKeyField = "UID"
        dgProducts.DataSource = ds
        Session("datasource") = ds
        dgProducts.DataBind()


       



    End Sub



    Private Sub ProcessCheckBoxes()
        Dim checkBox As System.Web.UI.WebControls.CheckBox
        Dim key As String
        For Each item As DataGridItem In dgProducts.Items
            Select Case item.ItemType
                Case ListItemType.Item, ListItemType.AlternatingItem
                    checkBox = CType(item.Controls(2).FindControl("chkSelected"), System.Web.UI.WebControls.CheckBox)
                    If Not IsNothing(checkBox) Then
                        key = dgProducts.DataKeys(item.ItemIndex).ToString()
                        If checkBox.Checked = True And (CompletedList.ContainsKey(key) = False Or CType(CompletedList(key), Boolean) = False) Then
                            CompletedList(key) = True
                        ElseIf checkBox.Checked = False And CompletedList.ContainsKey(key) = True And CType(CompletedList(key), Boolean) = True Then
                            CompletedList(key) = False
                        End If
                    End If

            End Select

        Next
    End Sub

    Public Function TODouble(ByVal val As String) As Double
        Return FormatCurrency(val, 2, TriState.True, TriState.True, TriState.True)

    End Function

    Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click


        Dim sb As StringBuilder = New StringBuilder
        ProcessCheckBoxes()
        sb.Append("<table>")
        sb.Append("<tr><th>Order Checked</th></tr>")
        For Each entry As DictionaryEntry In CompletedList
            If CType(entry.Value, Boolean) = True Then
                sb.AppendFormat("<tr><td>{0}</td></tr>", entry.Key)
            End If
        Next
        sb.Append("</table>")
        Literal1.Text = sb.ToString()











        'check if more than 4 have been Selected

        Dim nCount As Integer
        For Each dgItem As DataGridItem In dgProducts.Items
            CheckBox = CType(dgItem.FindControl("chkSelected"), CheckBox)
            If CheckBox.Checked = True Then
                nCount += 1
            End If
            If nCount >= 4 Then
                lblMessage.Text = "You may only select 4 items to be featured"
                Exit Sub

            End If


        Next
        nCount = 0
        'Update the featured items for the selected toplevel category
        Dim products As New FeaturedProducts.NFeaturedProduct
        Dim oFeaturedProduct As New SystemBase.NFeaturedProductBase

        For Each dgItem As DataGridItem In dgProducts.Items
            CheckBox = CType(dgItem.FindControl("chkSelected"), CheckBox)
            If CheckBox.Checked = True Then
                nCount += 1
                If nCount <= 4 Then
                    Dim FeaturedProductMGR As New BusinessRule.FeaturedProducts.NFeaturedProduct

                    Dim oFeaturedItem As New SystemBase.NFeaturedProductBase
                    oFeaturedItem.CategoryID = ddlCategory.SelectedValue
                    oFeaturedItem.FeaturedProductNumber = nCount
                    oFeaturedItem.ImageSmallPath = CType(dgItem.Cells(5).Text, String)
                    oFeaturedItem.Name = CType(dgItem.Cells(1).Text, String)
                    oFeaturedItem.UID = CType(dgItem.Cells(0).Text, Integer)
                    FeaturedProductMGR.SaveFeaturedProducts(oFeaturedItem)
                End If

            End If



        Next



    End Sub

End Class




and the client side page:
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="n_FeaturedProductAdmin.ascx.vb" Inherits="StoreFront.StoreFront.n_FeaturedProductAdmin" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<TABLE id="Table1" style="WIDTH: 736px; HEIGHT: 296px" width="736" border="1">
      <TR>
            <TD vAlign="top" width="20%"><asp:label id="Label1" Width="208px" runat="server">Select A Landing Page Category</asp:label><asp:dropdownlist id="ddlCategory" Width="208px" runat="server" AutoPostBack="True" DataValueField="ID"
                        DataTextField="Name"></asp:dropdownlist></TD>
            <TD vAlign="bottom" align="right" width="30%" colSpan="2" rowSpan="1"><asp:datagrid id="dgProducts" Width="568px" runat="server" AutoGenerateColumns="False" PageSize="10"
                        AllowPaging="True" OnPageIndexChanged="NewPage" DataKeyField="UID" PagerStyle-Mode="NumericPages" EnableViewState=True>
                        <Columns>
                              <asp:TemplateColumn HeaderText="Selected">
                                    <ItemTemplate>
                                          <asp:CheckBox ID="chkSelected" Runat="server" ></asp:CheckBox>
                                    </ItemTemplate>
                              </asp:TemplateColumn>
                              
                                      
                              <asp:BoundColumn Visible="False" DataField="UID"></asp:BoundColumn>
                              <asp:BoundColumn DataField="Name" HeaderText="Name" ItemStyle-Width="320px"></asp:BoundColumn>
                              <asp:BoundColumn DataField="Code" HeaderText="Code" ItemStyle-Width="60px"></asp:BoundColumn>
                              <asp:BoundColumn DataField="Price" HeaderText="Price" DataFormatString="{0:C}"></asp:BoundColumn>
                              <asp:BoundColumn DataField="Cost" HeaderText="Cost" DataFormatString="{0:C}"></asp:BoundColumn>
                              <asp:TemplateColumn HeaderText="Image">
                                    <ItemTemplate>
                                          <img src='http://almira/estore_tech/<%# DataBinder.Eval(Container.DataItem,"ImageSmallPath") %>' border=0 id="ThumbImg">
                                    </ItemTemplate>
                              </asp:TemplateColumn>
                        </Columns>
                        <PagerStyle PageButtonCount="10"></PagerStyle>
                  </asp:datagrid><asp:button id="btnUpdate" runat="server" Text="Update Featured Products"></asp:button></TD>
            <TD vAlign="top" align="center" width="30%"></TD>
            <TD width="20%"></TD>
      </TR>
      <TR>
            <TD vAlign="top" width="20%"></TD>
            <TD vAlign="bottom" align="center" width="30%" colSpan="2">&nbsp;Featured Products
                  for the Selected Category</TD>
            <TD vAlign="top" align="center" width="30%"></TD>
            <TD width="20%"></TD>
      </TR>
      <TR>
            <TD width="20%"></TD>
            <TD vAlign="top" align="center" width="30%"><A
      href="http://servername/estore_tech/detail.aspx?ID=<%=GetProductID(1)%>"
      ><asp:image id="imgProduct1" runat="server"></asp:image></A><BR>
                  <asp:hyperlink id="Product1Description" Runat="server"></asp:hyperlink><BR>
            </TD>
            <TD vAlign="top" align="center" width="30%"><A
      href="http://servername/estore_tech/detail.aspx?ID=<%=GetProductID(2)%>"
      ><asp:image id="imgProduct2" runat="server"></asp:image>&nbsp;</A>
                  <BR>
                  <asp:hyperlink id="Product2Description" runat="server"></asp:hyperlink><BR>
            </TD>
            <TD width="20%"></TD>
      </TR>
      <TR>
            <TD width="20%"></TD>
            <TD vAlign="top" align="center" width="30%"><A
      href="http://servername/estore_tech/detail.aspx?ID=<%=GetProductID(3)%>"
      ><asp:image id="imgProduct3" runat="server"></asp:image>&nbsp;</A>
                  <BR>
                  <asp:hyperlink id="Product3Description" runat="server"></asp:hyperlink><BR>
            </TD>
            <BR>
            <TD vAlign="top" align="center" width="30%"><A
      href="http://servername/estore_tech/detail.aspx?ID=<%=GetProductID(4)%>"
      ><asp:image id="imgProduct4" runat="server"></asp:image>&nbsp;</A>
                  <BR>
                  <asp:hyperlink id="Product4Description" runat="server"></asp:hyperlink><BR>
            </TD>
            <TD width="20%"></TD>
      </TR>
</TABLE>
<P></P>
<asp:label id="lblMessage" runat="server"></asp:label>

peterdidowAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

peterdidowAuthor Commented:
NOTE: When I step through ProcessCheckBoxes(), checkbox.check is always false....not sure why.
0
Bob LearnedCommented:
That is too much code.  Where is the check box column defined?

Bob
0
peterdidowAuthor Commented:
here is the code that actually pertains to the datagrid/checkbox.

 Private Sub dgProducts_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgProducts.ItemDataBound
        Dim checkBox As System.Web.UI.WebControls.CheckBox
        Dim key As String
        Select Case e.Item.ItemType
            Case ListItemType.Item, ListItemType.AlternatingItem
                checkBox = CType(e.Item.Controls(0).FindControl("CompletedCheckBox"), System.Web.UI.WebControls.CheckBox)
                If Not IsNothing(checkBox) Then
                    key = dgProducts.DataKeys(e.Item.ItemIndex).ToString()
                    If Not CompletedList.ContainsKey(key) Then
                        checkBox.Checked = False
                    Else
                        checkBox.Checked = CType(CompletedList(key), Boolean)
                    End If

                End If
        End Select
        'key = dgProducts.DataKeys(e.Item.ItemIndex).ToString()
        'If dgProducts.DataKeyField = CompletedList(key) Then
        '    'check it true

        'Else
        '    'unchecked.

        'End If


    End Sub

    Private Sub ProcessCheckBoxes()
        Dim checkBox As New System.Web.UI.WebControls.CheckBox
        Dim key As String
        For Each item As DataGridItem In dgProducts.Items
            Select Case item.ItemType
                Case ListItemType.Item, ListItemType.AlternatingItem
                    checkBox = CType(item.Controls(0).FindControl("chkSelected"), System.Web.UI.WebControls.CheckBox)

                    If Not IsNothing(checkBox) Then
                        key = dgProducts.DataKeys(item.ItemIndex).ToString()
                        If checkBox.Checked = True And (CompletedList.ContainsKey(key) = False Or CType(CompletedList(key), Boolean) = False) Then
                            CompletedList(key) = True
                        ElseIf checkBox.Checked = False And CompletedList.ContainsKey(key) = True And CType(CompletedList(key), Boolean) = True Then
                            CompletedList(key) = False
                        End If
                    End If

            End Select

        Next
    End Sub
    Private ReadOnly Property CompletedList() As Hashtable
        Get
            Dim hashtable As hashtable
            If IsNothing(ViewState("Completed")) Then
                hashtable = New hashtable
                ViewState("Completed") = hashtable
            Else
                hashtable = CType(ViewState("Completed"), hashtable)
            End If
            Return hashtable
        End Get
    End Property

    Public Sub BindData(ByVal val As Integer)
        'Get the First Level Children for the selected Landing Page Category
        Dim CategoryMGR As New BusinessRule.CCategories
        Dim products As New FeaturedProducts.NFeaturedProduct
        Dim c As New CXMLCategoryList
        Dim oCatArray As ArrayList
        Dim x As Integer
        Dim oArray As ArrayList

        oCatArray = CategoryMGR.GetFirstLevelChildren(ddlCategory.SelectedValue)
        'Get Products by Category for each of the child categories


        For x = 0 To oCatArray.Count - 1
            c = oCatArray(x)
            oArray = CategoryMGR.GetAllProductsByCategory(c.ID) 'the productid is returned.
        Next

        'the uid in the product table is the productid from above
        ' We need to grab the product data for each item in the arraylist (each product)


        'GetProductData
        dgProducts.CurrentPageIndex = val
        If Not Page.IsPostBack Then
            Dim ds As New DataSet
            ds = products.LoadProductsForCategories(oArray)

            dgProducts.DataKeyField = "UID"
            dgProducts.DataSource = ds.Tables(0).DefaultView
            Session("DS") = ds
            dgProducts.DataBind()
        Else
            If Not Session("DS") Is Nothing Then
                dgProducts.DataSource = Session("DS")
                dgProducts.DataBind()
            Else

                Dim ds As New DataSet
                ds = products.LoadProductsForCategories(oArray)

                dgProducts.DataKeyField = "UID"
                dgProducts.DataSource = ds.Tables(0).DefaultView
                Session("DS") = ds
                dgProducts.DataBind()
            End If





        End If


    End Sub

    Public Sub NewPage(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgProducts.PageIndexChanged

        ProcessCheckBoxes()
        BindData(e.NewPageIndex)
        dgProducts.CurrentPageIndex = e.NewPageIndex


    End Sub

    Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click


        Dim sb As StringBuilder = New StringBuilder
        ProcessCheckBoxes()
        sb.Append("<table>")
        sb.Append("<tr><th>Order Checked</th></tr>")
        For Each entry As DictionaryEntry In CompletedList
            If CType(entry.Value, Boolean) = True Then
                sb.AppendFormat("<tr><td>{0}</td></tr>", entry.Key)
            End If
        Next
        sb.Append("</table>")
        literal1.Text = sb.ToString()



        'check if more than 4 have been Selected

        Dim nCount As Integer
        For Each dgItem As DataGridItem In dgProducts.Items
            CheckBox = CType(dgItem.FindControl("chkSelected"), CheckBox)
            If CheckBox.Checked = True Then
                nCount += 1
            End If
            If nCount >= 4 Then
                lblMessage.Text = "You may only select 4 items to be featured"
                Exit Sub

            End If


        Next
        nCount = 0
        'Update the featured items for the selected toplevel category
        Dim products As New FeaturedProducts.NFeaturedProduct
        Dim oFeaturedProduct As New SystemBase.NFeaturedProductBase

        For Each dgItem As DataGridItem In dgProducts.Items
            CheckBox = CType(dgItem.FindControl("chkSelected"), CheckBox)
            If CheckBox.Checked = True Then
                nCount += 1
                If nCount <= 4 Then
                    Dim FeaturedProductMGR As New BusinessRule.FeaturedProducts.NFeaturedProduct

                    Dim oFeaturedItem As New SystemBase.NFeaturedProductBase
                    oFeaturedItem.CategoryID = ddlCategory.SelectedValue
                    oFeaturedItem.FeaturedProductNumber = nCount
                    oFeaturedItem.ImageSmallPath = CType(dgItem.Cells(5).Text, String)
                    oFeaturedItem.Name = CType(dgItem.Cells(1).Text, String)
                    oFeaturedItem.UID = CType(dgItem.Cells(0).Text, Integer)
                    FeaturedProductMGR.SaveFeaturedProducts(oFeaturedItem)
                End If

            End If



        Next



    End Sub
0
Bob LearnedCommented:
You are rebinding the DataGrid after each page access:

 dgProducts.DataSource = CType(Session("datasource"), DataSet)
 dgProducts.DataBind()

You aren't checking for Page.IsPostBack before binding, so all is lost when you rebind.

Bob
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.