locked
GridView - Preserve checkbox status after paging - no direct calling DataBind() RRS feed

  • Question

  • User-1546444994 posted

    Dear all,

    Sorry it may sound impolite, but please read the post before posting those modal answer. My problem may be different than those modal answer.

    I have struggled with this for sometime. Please help.

    I have a pretty standard page. At top there are some filters that user can select to reduce the number of resulting rows (like changing the data from and date to.) In the middle there are two buttons. One is to query the database again, but with filtering at top. The second button is to print selected row. So the GridView following has checkbox as the first column. it also has paging enabled. There is a SqlDataSource at the bottom which GridView's DataSourceID is pointing to.

    I find out the GridView does not keep track of which rows has been ticked after paging. I search the web and find Preserving state of Checkboxes while paging in ASP.Net GridView Control. This involves calling GridView1.DataBind() directly. As my understanding, if GridView's DataSourceID is specified, the DataBind() occurs automatically. So whenever there is an explicit call to DataBind(), I remove it. However the rechecking (re-ticking) the checkbox does not appear. I step through the code, but the page just does not show it.

    If I add back the DataBind() statement, the check disappears immediately after I click on it! 

    Question: How do I get the GridView to keep track of checkboxes that I have ticked? Please note

    1. I want to keep it simple. So I don't want to fill in a System.Data.DataTable first before binding to GridView. (I have searched the web and all suggest this way! :( )
    2. When the page is first shown, there is a query to the database, but the resulting rows is zero (0). (Don't know if this helps.) User have to adjust the data from to Today - 4 months, press Query button to get some rows.
    3. I do not have 'Check All' mechanism. 

    Here is the source code:

    Imports System
    Imports System.Collections
    
    Partial Class _Default
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim startData As Date = Date.Today.AddMonths(-1)
            Dim buildQueryString As String = String.Empty
            Dim checkBoxArray As ArrayList
            Dim chk As CheckBox
            Dim checkBoxIndex As Integer
    
            If Not IsPostBack() Then
                txtSDOCDate.Text = startData.ToString("yyyyMMdd")
                txtEDOCDate.Text = Date.Today.ToString("yyyyMMdd")
    
                'set SQL string
                ds001DocList.SelectCommand = "SELECT * FROM [vWEB001_DocList] " _
                    & "WHERE ([UsrID] = '" & Session("UsrID") & "') " _
                    & "AND DOC_DATE >= '" & txtSDOCDate.Text & "' " _
                    & "AND DOC_DATE <= '" & txtEDOCDate.Text & "' " _
                    & "ORDER BY [DOC_DATE] DESC, [DOC_ID] DESC"
            Else
                getQuery(buildQueryString)
                ds001DocList.SelectCommand = buildQueryString
    
                ' From ASP Snippets
                If ViewState("checkBoxArray") IsNot Nothing Then
                    checkBoxArray = DirectCast(ViewState("checkBoxArray"), ArrayList)
                Else
                    checkBoxArray = New ArrayList()
                End If
    
                ' Preserve check box state
                For i As Integer = 0 To gvQuery.Rows.Count - 1
                    If gvQuery.Rows(i).RowType = DataControlRowType.DataRow Then
                        chk = DirectCast(gvQuery.Rows(i).Cells(0).FindControl("cbSelectRow"), CheckBox)
                        checkBoxIndex = gvQuery.PageSize * gvQuery.PageIndex + (i + 1)
    
                        If chk.Checked Then
                            If checkBoxArray.IndexOf(checkBoxIndex) = -1 Then
                                checkBoxArray.Add(checkBoxIndex)
                            End If
                        Else
                            If checkBoxArray.IndexOf(checkBoxIndex) <> -1 Then
                                checkBoxArray.Remove(checkBoxIndex)
                            End If
                        End If
                    End If
                Next
                ViewState("checkBoxArray") = checkBoxArray
            End If
            ' Force to DataBind()
            gvQuery.DataBind()  ' *** If I have this, the checkbox disappears immdiately
        End Sub
    
        Private Sub getQuery(ByRef queryString As String)
            queryString = "SELECT * FROM [vWEB001_DocList] " _
                    & "WHERE ([UsrID] = '" & Session("UsrID") & "') "
    
            ' Document #
            If txtDocID.Text <> String.Empty Then
                queryString &= "AND DOC_ID LIKE " & txtDocID.Text.Trim() & "%' "
            End If
            ' Document Date
            If txtSDOCDate.Text <> String.Empty Then
                queryString &= "AND DOC_DATE >= '" & txtSDOCDate.Text & "' "
            End If
            If txtEDOCDate.Text <> String.Empty Then
                queryString &= "AND DOC_DATE <= '" & txtEDOCDate.Text & "' "
            End If
    		
    		' Other type of filtering
        End Sub
    
        Protected Sub btnQuery_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnQuery.Click
            Dim buildNewQuery As String = String.Empty
    
            getQuery(buildNewQuery)
            ' Run query
            ds001DocList.SelectCommand = buildNewQuery
            gvQuery.DataBind()
            ' Take care the index as well
            gvQuery.PageIndex = 0
        End Sub
    
        Protected Sub gvQuery_PageIndexChanging(ByVal sender As Object, _
                      ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) _
                      Handles gvQuery.PageIndexChanging
            gvQuery.PageIndex = e.NewPageIndex
    
            Dim checkBoxArray As ArrayList
            Dim chk As CheckBox
            Dim checkBoxIndex As Integer
    
            If ViewState("checkBoxArray") IsNot Nothing Then
                checkBoxArray = DirectCast(ViewState("checkBoxArray"), ArrayList)
    
                For i As Integer = 0 To gvQuery.Rows.Count - 1
                    If gvQuery.Rows(i).RowType = DataControlRowType.DataRow Then
                        chk = DirectCast(gvQuery.Rows(i).Cells(0).FindControl("cbSelectRow"), CheckBox)
                        checkBoxIndex = (gvQuery.PageSize * gvQuery.PageIndex) + (i + 1)
    
                        If checkBoxArray.IndexOf(checkBoxIndex) <> -1 Then
                            chk.Checked = True
                        End If
                    End If
                Next
            End If
        End Sub
    End Class
    

    Tuesday, December 27, 2016 8:34 AM

All replies

  • User-271186128 posted

    Hi kaiclassic,

    How do I get the GridView to keep track of checkboxes that I have ticked? Please note

    Please set ds001DocList as datasource of gvQuery after you set the SelectCommand in method, such as btnQuery_Click() and gvQuery_PageIndexChanging()

    It can fix your paging problem.

    I have modified your code. Now it can keep the track of the rows.

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim startData As Date = Date.Today.AddMonths(-1)
            Dim buildQueryString As String = String.Empty
            Dim checkBoxArray As ArrayList
            Dim chk As CheckBox
            Dim checkBoxIndex As Integer
    
    
            If ViewState("checkBoxArray") IsNot Nothing Then
                checkBoxArray = DirectCast(ViewState("checkBoxArray"), ArrayList)
            Else
                checkBoxArray = New ArrayList()
            End If
            If Not IsPostBack() Then
                txtSDOCDate.Text = startData.ToString("yyyyMMdd")
                txtEDOCDate.Text = Date.Today.ToString("yyyyMMdd")
    
    
                ds001DocList.SelectCommand = "SELECT * FROM [vWEB001_DocList] " _
                    & "WHERE ([UsrID] = '" & Session("UsrID") & "') " _
                    & "AND DOC_DATE >= '" & txtSDOCDate.Text & "' " _
                    & "AND DOC_DATE <= '" & txtEDOCDate.Text & "' " _
                    & "ORDER BY [DOC_DATE] DESC, [DOC_ID] DESC"
                gvQuery.DataSource = ds001DocList          
                gvQuery.DataBind()
    
            Else
                For i As Integer = 0 To gvQuery.Rows.Count - 1
                    If gvQuery.Rows(i).RowType = DataControlRowType.DataRow Then
                        chk = DirectCast(gvQuery.Rows(i).Cells(0).FindControl("cbSelectRow"), CheckBox)
                        checkBoxIndex = gvQuery.PageSize * gvQuery.PageIndex + (i + 1)
                        If chk.Checked Then
                            If checkBoxArray.IndexOf(checkBoxIndex) = -1 Then
                                checkBoxArray.Add(checkBoxIndex)
                            End If
                        Else
                            If checkBoxArray.IndexOf(checkBoxIndex) <> -1 Then
                                checkBoxArray.Remove(checkBoxIndex)
                            End If
                        End If
                    End If
                Next
                ViewState("checkBoxArray") = checkBoxArray
            End If
        End Sub
    
    
        Private Sub getQuery(ByRef queryString As String)
            queryString = "SELECT * FROM [vWEB001_DocList] " _
                    & "WHERE ([UsrID] = '" & Session("UsrID") & "') "
            'Document #
            If txtDocID.Text <> String.Empty Then
                queryString &= "AND DOC_ID LIKE " & txtDocID.Text.Trim() & "%' "
            End If
            'Document Date
            If txtSDOCDate.Text <> String.Empty Then
                queryString &= "AND DOC_DATE >= '" & txtSDOCDate.Text & "' "
            End If
            If txtEDOCDate.Text <> String.Empty Then
                queryString &= "AND DOC_DATE <= '" & txtEDOCDate.Text & "' "
            End If
    
        End Sub
    
        Protected Sub btnQuery_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnQuery.Click
            Dim buildNewQuery As String = String.Empty
    
            getQuery(buildNewQuery)
            ds001DocList.SelectCommand = buildNewQuery
            gvQuery.DataSource = ds001DocList
            gvQuery.PageIndex = 0
            gvQuery.DataBind()
        End Sub
    
        Protected Sub gvQuery_PageIndexChanging(ByVal sender As Object,
                      ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) _
                      Handles gvQuery.PageIndexChanging
    
            Dim buildNewQuery As String = String.Empty
            getQuery(buildNewQuery)
            ds001DocList.SelectCommand = buildNewQuery
            gvQuery.DataSource = ds001DocList
            gvQuery.PageIndex = e.NewPageIndex
            gvQuery.DataBind()
    
            Dim checkBoxArray As ArrayList
            Dim chk As CheckBox
            Dim checkBoxIndex As Integer
    
            If ViewState("checkBoxArray") IsNot Nothing Then
                checkBoxArray = DirectCast(ViewState("checkBoxArray"), ArrayList)
    
                For i As Integer = 0 To gvQuery.Rows.Count - 1
                    If gvQuery.Rows(i).RowType = DataControlRowType.DataRow Then
                        chk = DirectCast(gvQuery.Rows(i).Cells(0).FindControl("cbSelectRow"), CheckBox)
                        checkBoxIndex = (gvQuery.PageSize * gvQuery.PageIndex) + (i + 1)
    
                        If checkBoxArray.IndexOf(checkBoxIndex) <> -1 Then
                            chk.Checked = True
                        End If
                    End If
                Next
            End If
        End Sub
    

    Besides, here is an article about Preserving state of Checkboxes while paging in ASP.Net GridView Control. You could check it.

    Best regards,
    Dillion

               

    Wednesday, December 28, 2016 9:52 AM