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