vendredi 21 avril 2017

Persisting Checkbox State when Paging Gridview

In a nutshell, I am trying to maintain the CheckBox state on a GridView while paging. I am successfully tracking the CheckBox states in the ViewState (using an ArrayList on the row IDs) and I can successfully perform an action on all the checked rows on multiple pages.

However, once I go to a new page and then page back, the checked CheckBoxes are no longer checked (though the row ID still exists in the ArrayList in the ViewState). I have to assume this has something to do with the page life cycle.

I have read the entire ASP.NET Page Life Cycle Overview and tried binding the GridView in the PreRender event (and not binding the GridView at all) which didn't work either. All the examples I found online were loading the GridView DataSource from code behind using a DataTable filled from a SQLDataAdapter. I am using a DataSourceID (from a SQLDataSource) assigned directly to the GridView.

I still can't seem to determine why this is failing. Thanks in advance for your time.

ASPX Page

<asp:SqlDataSource ID="sdsAdminIntakes" runat="server" CancelSelectOnNullParameter="false"
    Connectionstring="<%$ ConnectionStrings:MyAppSiteDB %>"
    ProviderName="<%$ ConnectionStrings:MyAppSiteDB.ProviderName %>"
    SelectCommand="admin_intakes_search"
    SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter Name="specialist_id" />
        <asp:Parameter Name="caller_name" />
        <asp:Parameter Name="case_number" />
        <asp:Parameter Name="case_status" />
    </SelectParameters>
</asp:SqlDataSource>

<asp:GridView ID="grdAdminIntakes" runat="server"
    DataKeyNames="intake_id" DataSourceID="sdsAdminIntakes"
    AutoGenerateColumns="False" AllowSorting="True"
    AllowPaging="True" PageSize="20">
    <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:CheckBox runat="server" ID="chkAll" />
            </HeaderTemplate>
            <ItemTemplate>
                <asp:CheckBox runat="server" ID="chkIntake" />
            </ItemTemplate>
        </asp:TemplateField>

        <asp:BoundField DataField="specialist_full_name" HeaderText="Current Specialist"
            SortExpression="specialist_full_name" >
        </asp:BoundField>
        <asp:BoundField DataField="caller_name" HeaderText="Caller"
            SortExpression="caller_name" >
        </asp:BoundField>
        <asp:BoundField DataField="case_number" HeaderText="Case #"
            SortExpression="case_number" >
        </asp:BoundField>
        <asp:BoundField DataField="cmp_status" HeaderText="Case Status"
            SortExpression="case_status" ItemStyle-CssClass="case_status" >
        </asp:BoundField>
    </Columns>
</asp:GridView>

ASPX.VB Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        grdAdminIntakes.DataBind()
    End If
End Sub

Private Sub grdAdminIntakes_PageIndexChanging(sender As Object, e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles grdAdminIntakes.PageIndexChanging
    GetCheckboxState()
    grdAdminIntakes.PageIndex = e.NewPageIndex
    grdAdminIntakes.DataBind()
    SetCheckboxState()
End Sub

Private Sub GetCheckboxState()
    Dim lstArray As ArrayList
    If ViewState("SelectedRecords") IsNot Nothing Then
        lstArray = DirectCast(ViewState("SelectedRecords"), ArrayList)
    Else
        lstArray = New ArrayList()
    End If
    Dim chkAll As CheckBox = DirectCast(grdAdminIntakes.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
    For i As Integer = 0 To grdAdminIntakes.Rows.Count - 1
        If chkAll.Checked Then
            If Not lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
                lstArray.Add(grdAdminIntakes.DataKeys(i).Value)
            End If
        Else
            Dim chk As CheckBox = DirectCast(grdAdminIntakes.Rows(i).Cells(0).FindControl("chkIntake"), CheckBox)
            If chk.Checked Then
                If Not lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
                    lstArray.Add(grdAdminIntakes.DataKeys(i).Value)
                End If
            Else
                If lstArray.Contains(grdAdminIntakes.DataKeys(i).Value) Then
                    lstArray.Remove(grdAdminIntakes.DataKeys(i).Value)
                End If
            End If
        End If
    Next
    ViewState("SelectedRecords") = lstArray
End Sub

Private Sub SetCheckboxState()
    Dim currentCount As Integer = 0
    Dim chkAll As CheckBox = DirectCast(grdAdminIntakes.HeaderRow.Cells(0).FindControl("chkAll"), CheckBox)
    chkAll.Checked = True
    Dim lstArray As ArrayList = DirectCast(ViewState("SelectedRecords"), ArrayList)
    For i As Integer = 0 To grdAdminIntakes.Rows.Count - 1
        Dim chk As CheckBox = DirectCast(grdAdminIntakes.Rows(i).Cells(0).FindControl("chkIntake"), CheckBox)
        If chk IsNot Nothing Then
            chk.Checked = lstArray.Contains(grdAdminIntakes.DataKeys(i).Value)
            If Not chk.Checked Then
                chkAll.Checked = False
            Else
                currentCount += 1
            End If
        End If
    Next
End Sub




Aucun commentaire:

Enregistrer un commentaire