But it give me an error - “Parser Error Message: ‘cblSubscriptions_<%# Container.DataItem(“EmailID”)%>’ is not a valid identifier.” on the red text above.
Then to bind the CheckboxList items and select the subscriptions by calling the control via the dynamic assigned ID:
Private Sub BindSubscriptions(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
If e.Item.ItemType = ListItemType.Item Or _
e.Item.ItemType = ListItemType.AlternatingItem Then
Dim cblSubscriptions As CheckBoxList = e.Item.FindControl("cblSubscriptions_" & e.Item.DataItem("EmailID"))
objConn.Close()
objConn.Open()
objCmd = New SqlCommand("SELECT * FROM tlkpDistribution ORDER BY Name", objConn)
objRdr = objCmd.ExecuteReader()
cblSubscriptions.DataSource = objRdr
cblSubscriptions.DataValueField = "DistributionID"
cblSubscriptions.DataTextField = "Name"
cblSubscriptions.DataBind()
objRdr.Close()
'Get subscriptions and select CheckBoxList item selections
objCmd = New SqlCommand("SELECT * FROM tblSubscription WHERE (UserID=" & strUserID & ") AND (EmailID=" & e.Item.DataItem("EmailID") & ")", objConn)
objRdr = objCmd.ExecuteReader()
While objRdr.Read()
If Not cblSubscriptions.Items.FindByValue(objRdr.Item("DistributionID").ToString) Is Nothing Then
cblSubscriptions.Items.FindByValue(objRdr.Item("DistributionID").ToString).Selected = True
End If
End While
objRdr.Close()
objConn.Close()
End If
End Sub
to access each CheckBoxList in everyone of your RepeaterItems. I think for VB.NET you just change [i] to (i). Just put that in a for loop in your button submit event method and you will have access to all the CheckBoxLists.
Also, you are going to have to upgrade that repeater to a DataList. Think of a repeater like a DataReader. They are both fast, forward only, output only. Going back and forth is a bit tricky without other persistence options.
I think you are making it more complicated than it really is.
A repeater is a namingcontainer meaning that each item will act as a seperate namespace. Therefore, there’s no need to assign page-wide unique IDs to items in the template. Just assign any ID that unique within the template. This will do:
even if you assign a page-wide unique ID it will still be “nested” inside the repeater (another effect of the repeater being a namingcontainer).
Now to find the checkboxlist during the ItemCreated event just do
Dim cblSubscriptions As CheckBoxList = e.Item.FindControl("cblSubscriptions" )
The error message that you are getting is b/c you are using a databinding expression to generate an identifier. Databinding occurs too late in the page lifecycle to be used to generate identifiers dynamically. And as outlines above there’s really no need.
As a sidenote, this is also why controls have both an ID and a ClientID property: The ID property is the declared (local if you will) identifier, while ClientID id the “global” ID that has been prefixed with the naming container’s identifier. This is the ID that can be used from javascript.
What Benjymouse said would sort you out no problem.
I didn’t claim that using datalist would sort out his problem. My first post answered his original problem, and even explained why he was having the problem.
Ok, I have changed the code so that it is a DataList.
I now have the following error which I dont inderstand:
This code binds the DataList
Private Sub BindEmailDataList()
objConn.Open()
objCmd = New SqlCommand("SELECT * FROM tblUserEmail WHERE UserID=" & strUserID & " ORDER BY Email", objConn)
objRdr = objCmd.ExecuteReader()
dlEmailSubscriptions.DataSource = objRdr
dlEmailSubscriptions.DataBind()
objRdr.Close()
objConn.Close()
End Sub
Then on creation the following is done on each row to bind the datalist.
Public Sub dlEmailSubscriptions_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs)
If e.Item.ItemType = ListItemType.Item Or _
e.Item.ItemType = ListItemType.AlternatingItem Then
Dim cblSubscriptions As CheckBoxList = e.Item.FindControl("cblSubscriptions")
Dim objEmailRdr As SqlDataReader
Dim objEmailCmd As SqlCommand
objEmailCmd = New SqlCommand("SELECT * FROM tlkpDistribution ORDER BY Name", objConn)
[COLOR=Red]objEmailRdr = objEmailCmd.ExecuteReader()[/COLOR]
cblSubscriptions.DataSource = objEmailRdr
cblSubscriptions.DataValueField = "DistributionID"
cblSubscriptions.DataTextField = "Name"
cblSubscriptions.DataBind()
objEmailRdr.Close()
End If
End Sub
This returns the following error for the line highlighted above: There is already an open DataReader associated with this Connection which must be closed first.
I don’t understand this error as the reader for the DataList is declared as objRdr while this one is objEmailRdr.
I also tried closing the objRdr, but then I get: Invalid attempt to FieldCount when reader is closed
I have changed my code to make use of a DataView and DataAdaptor.
My next question is, how do I set the values as SELECTED for items? I have tried the code below and it execute without errors, but nothing is selected.
My code:
Public Sub dlEmailSubscriptions_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs)
If e.Item.ItemType = ListItemType.Item Or _
e.Item.ItemType = ListItemType.AlternatingItem Then
Dim cblSubscriptions As CheckBoxList = e.Item.FindControl("cblSubscriptions")
Dim objEmailDA As SqlDataAdapter
Dim objEmailDS As New DataSet
Dim objEmailDV As DataView
objEmailDA = New SqlDataAdapter("SELECT * FROM tlkpDistribution ORDER BY Name", objConn)
objEmailDA.Fill(objEmailDS, "DistributionLists")
objEmailDV = objEmailDS.Tables("DistributionLists").DefaultView
cblSubscriptions.DataSource = objEmailDV
cblSubscriptions.DataValueField = "DistributionID"
cblSubscriptions.DataTextField = "Name"
cblSubscriptions.DataBind()
'Get subscriptions and select CheckBoxList item selections
Dim EmailID As String
Dim DistributionID As String
objConn.Open()
objCmd = New SqlCommand("SELECT tblSubscription.EmailID, tblSubscription.DistributionID, tlkpDistribution.Name AS DistriburtionList, tblUser.UserID, tblUser.Username, tblUserEmail.Email, tblUser.Name, tblUser.Surname FROM tlkpDistribution RIGHT OUTER JOIN tblSubscription ON tlkpDistribution.DistributionID = tblSubscription.DistributionID LEFT OUTER JOIN tblUser LEFT OUTER JOIN tblUserEmail ON tblUser.UserID = tblUserEmail.UserID ON tblSubscription.EmailID = tblUserEmail.EmailID WHERE (tblSubscription.EmailID=" & e.Item.DataItem("EmailID") & ")", objConn)
objRdr = objCmd.ExecuteReader()
While objRdr.Read()
EmailID = objRdr.Item("EmailID").ToString
DistributionID = objRdr.Item("DistributionID").ToString
If Not cblSubscriptions.Items.FindByValue(objRdr.Item("DistributionID").ToString) Is Nothing Then
cblSubscriptions.Items.FindByValue(objRdr.Item("DistributionID").ToString).Selected = True
End If
End While
objConn.Close()
End If
End Sub