CheckBoxList not maintaining Checked CheckBoxes when Nested

J

jmhmaine

I want to maintain the state of the checkboxes (Checked/Unchecked) between
posts. I'm able to do it when the CheckBoxList is directly under a Form, but
when it is nested in a DataList it doesn't maintain state.

Here is my ASPX Code:

<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="simpleData.aspx.vb" Inherits="simpleData" Trace="True" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>simpleData</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:DataList ID="dlEmail_Parent"
Runat="server"
RepeatLayout="Flow"
DataKeyField="FamilyID"
OnItemCommand="DoItemSelect"
OnCancelCommand="DoItemCancel"
EnableViewState="True">
<ItemTemplate>
<asp:ImageButton CommandName="Select"
ImageUrl='/images/page_elements/uparrow.gif' Height="10" Width="11"
runat="server" ID="Imagebutton1" EnableViewState=False />
<%# DataBinder.Eval(Container.DataItem, "FamilyName") %><br>
</ItemTemplate>
<SelectedItemTemplate>
<asp:ImageButton CommandName="Cancel"
ImageUrl='/images/page_elements/downarrow.gif' Height="10" Width="11"
runat="server" ID="Imagebutton2" EnableViewState=False />
<%# DataBinder.Eval(Container.DataItem, "FamilyName") %><br>
<asp:CheckBoxList id="chblEmailSignup"
DataSource='<%# GetChildRelation(Container.DataItem,
"PROJECT_FAMILY_PROJECT") %>'
DataMember='PROJECT'
DataTextField='ProjectName'
DataValueField='ProjectID'
EnableViewState="True"
BackColor="#C6D8DB"
CellPadding="2"
CellSpacing="0"
Runat="server">
</asp:CheckBoxList>
<br />
<asp:Button ID="btnSubmitSelections" Text="Submit Selections"
Runat="server" EnableViewState="False" OnClick="onSubmit_Clicked" />
<br />
</SelectedItemTemplate>
</asp:DataList>
<br />
<asp:Literal ID="ltrEmailSignup" Runat="server" EnableViewState=False />
</form>
</body>
</html>



Here is my VB Code Behind:

Imports System.Data.SqlClient

Public Class simpleData
Inherits System.Web.UI.Page

Protected WithEvents dlEmail_Parent As DataList
Protected WithEvents ltrEmailSignup As Literal

#Region " Web Form Designer Generated Code "

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

End Sub

'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

'Only Bind on First Load
If Not (IsPostBack) Then
bindData()
End If
End Sub


'====================================================================================
'Sub onSubmit_Clicked(ByVal sender As Object, ByVal e As
System.EventArgs)
'
'Called by btnSubmitSelections onClick from ASPX
'Will display a message about which items were select, or message
that no items were
'selected.

'====================================================================================
Sub onSubmit_Clicked(ByVal sender As Object, ByVal e As
System.EventArgs)
Dim cblSelected As CheckBoxList =
CType(dlEmail_Parent.Items(dlEmail_Parent.SelectedIndex).FindControl("chblEmailSignup"), CheckBoxList)
Dim i As Integer
Dim cntSelected As Integer = 0
Dim msgP1 As String = "<b>You have signed up for:</b><ul>"
Dim msgP2 As String = "</ul>"

' Iterate through the Items collection of the CheckBoxList
If (Not cblSelected Is Nothing) Then
For i = 0 To cblSelected.Items.Count - 1
If cblSelected.Items(i).Selected Then
cntSelected += 1
msgP1 &= "<li>" & cblSelected.Items(i).Text & "</li>"
End If
Next

If cntSelected > 0 Then
ltrEmailSignup.Text = msgP1 & msgP2
Else
ltrEmailSignup.Text = "<b>You must select at least one
item.</b>"
End If
Else
Trace.Write("Can not find Control")
End If
End Sub


'====================================================================================
'Sub bindData()
'
'Builds Dataset which is used for dlEmail_Parent datasource.
'chblEmailSignup depends on Child Table, set at Run time in ASPX page
'in SelectedItemTemplate of dlEmail_Parent.

'====================================================================================
Sub bindData()
Dim sqlParent As String = "SELECT FamilyID,FamilyName FROM
PROJECT_FAMILY;"
Dim sqlChild As String = "SELECT ProjectID, ProjectName,
FamilyID FROM PROJECT;"
Dim ds As New DataSet
Dim conn As New SqlConnection
Dim cmdParent, cmdChild As SqlCommand 'Two commands for the two
tables
Dim adpParent, adpChild As SqlDataAdapter 'Two datapaters to
fill the dataset from the two tables
Dim datarelation As datarelation 'Handles the relationship
between the two columns
Dim dcParent, dcChild As DataColumn 'Will store keys from tables

conn.ConnectionString = Global.ConnectionString

'Set Parent Command
cmdParent = New SqlCommand
cmdParent.Connection = conn
cmdParent.CommandText = sqlParent

'Set Child Command
cmdChild = New SqlCommand
cmdChild.Connection = conn
cmdChild.CommandText = sqlChild

'Fill the Parent table and add it to the dataset
adpParent = New SqlDataAdapter
adpParent.SelectCommand = cmdParent
adpParent.TableMappings.Add("Table", "PROJECT_FAMILY")
adpParent.Fill(ds)

'Fill the Child table and add it to the dataset
adpChild = New SqlDataAdapter
adpChild.SelectCommand = cmdChild
adpChild.TableMappings.Add("Table", "PROJECT")
adpChild.Fill(ds)

'Set the Columns to shared key
dcParent = ds.Tables("PROJECT_FAMILY").Columns("FamilyID")
dcChild = ds.Tables("PROJECT").Columns("FamilyID")

'Create a new datarelation object based on the the two datacolumns
datarelation = New datarelation("PROJECT_FAMILY_PROJECT",
dcParent, dcChild)
ds.Relations.Add(datarelation)

dlEmail_Parent.DataSource = ds.Tables("PROJECT_FAMILY")
dlEmail_Parent.DataBind()

adpParent.Dispose()
adpParent = Nothing
adpChild.Dispose()
adpChild = Nothing
ds.Dispose()
ds = Nothing
conn.Close()
conn = Nothing
End Sub

Function GetChildRelation(ByVal dataItem As Object, ByVal relation
As String) As DataView
'TODO: Test for Null DataItem
Dim drv As DataRowView = CType(dataItem, DataRowView)
Return drv.CreateChildView(relation)
End Function


'====================================================================================
'Sub DoItemSelect(ByVal objSource As Object, ByVal objArgs As
DataListCommandEventArgs)
'
'Handles the event of the Item Select Command from web page

'====================================================================================
Sub DoItemSelect(ByVal objSource As Object, ByVal objArgs As
DataListCommandEventArgs)
dlEmail_Parent.SelectedIndex = objArgs.Item.ItemIndex 'Set the
Seleted Item
bindData()
End Sub


'====================================================================================
'Sub DoItemCancel(ByVal objSource As Object, ByVal objArgs As
DataListCommandEventArgs)
'
'Handles the event of the Item Cancel Command from web page

'====================================================================================
Sub DoItemCancel(ByVal objSource As Object, ByVal objArgs As
DataListCommandEventArgs)
dlEmail_Parent.SelectedIndex = -1 'Leave Select Mode
bindData()
End Sub

End Class
 
S

Steven Cheng[MSFT]

Hi Jmhmaine,

Thanks for your posting. As for the keeping checkboxlist(nested in datagrid
control)'s check status between postbacks(submits), I think the problem
that the previous checked status lost when you swtich the selected item is
because such Template Databound control like datalist or datagrid, repeater
is datasource based and when we rebind these control, all the items will be
reset to the values according to the datasourse's value. In other word, if
we don't store the change into the actual datasource, the values will reset
to the old stats after rebinding.

One common solution is to store the retireved datasource( for example
DataSet) in the serverside's Session or Application Cache collection as
temporary datasource. Then each time the user submit the select item, we
change the temporary datasource according to the submited selected item's
values and then rebind the control with the updated datasource. Thus, all
the sequential swtiching will remain the previous change results.How do you
think of this?

If anything unclear or have any further questions, please feel free to post
here. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

jmhmaine

Steven:

I'm not re-binding while it is selected, so it should work but doesn't. When
I put the CheckBoxList in a Form by itself with the same properties and Code
Behind, it maintains the state between Posts. Could you point to a line in my
code that you think is reseting the values to uncheck? Thanks.

Josh.
 
J

jmhmaine

I found that all though I did not call the binding sub, that the DataList
automatically runs the OnItemCommand event within Posts of the Selected Item.
So I updated my code to test see if the button was clicked with:
If objArgs.CommandName = "Select" Then...

Updated Code:
Sub DoItemSelect(ByVal objSource As Object, ByVal objArgs As
DataListCommandEventArgs)
If objArgs.CommandName = "Select" Then
dlEmail_Parent.SelectedIndex = objArgs.Item.ItemIndex
bindData()
End If
End Sub
 
S

Steven Cheng[MSFT]

Hi Jmhmaine,

Thanks for your followup. Yes, that's just the
bindData() function you called in the ItemCommand make the datalist
rebinded and
clear the checkboxlists' status. Anyway, glad that you found it and fixed
the problem. If there is any further question later, please feel free to
post here also.

Good luck!

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top