Rouchie
asked on
Trying to place a ListControl in page_init
Within my page I have a list. In some cases this displays as a radiobuttonlist, and in other case as a checkboxlist.
This list is populated and read back by other subroutines. From various tutorials it seems that dynamic controls must be generated in page_init if they are to be available across postbacks.
Given the following code, how do I add this listcontrol to the page in order for other subs to cast it as either of the 2 correct list types?
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lc As ListControl
ph.Controls.Add(lc)
lc.ID = "lc"
End Sub
Sub rePopulate(ByVal aNumber As Boolean) ' called later in the page
Dim answers As ListControl = CType(ph.FindControl("lc") , ListControl)
answers.Items.Clear()
If aNumber Then
answers = New RadioButtonList
Else
answers = New CheckBoxList
End If
..... ' populate list items ....
End Sub
The page_init is giving an error:
Value cannot be null.
Parameter name: child
ph.Controls.Add(lc)
This list is populated and read back by other subroutines. From various tutorials it seems that dynamic controls must be generated in page_init if they are to be available across postbacks.
Given the following code, how do I add this listcontrol to the page in order for other subs to cast it as either of the 2 correct list types?
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lc As ListControl
ph.Controls.Add(lc)
lc.ID = "lc"
End Sub
Sub rePopulate(ByVal aNumber As Boolean) ' called later in the page
Dim answers As ListControl = CType(ph.FindControl("lc")
answers.Items.Clear()
If aNumber Then
answers = New RadioButtonList
Else
answers = New CheckBoxList
End If
..... ' populate list items ....
End Sub
The page_init is giving an error:
Value cannot be null.
Parameter name: child
ph.Controls.Add(lc)
ASKER
Hi Harshit,
Yes you are correct, however, when I do this:
Dim lc As New ListControl
I get this error:
BC30569: 'New' cannot be used on a class that is declared 'MustInherit'.
The sub called rePopulate is fired in the page when a certain link is clicked. Up until that point there should only be an empty listcontrol in the placeholder, so it shows nothing on screen. The problem is that rePopulate is called many times during the total page execution, and each time may set the listControl to be either radio buttons or check boxes, therefore I cannot set it as a specific type in page_init - it must remain generic at that point.
Yes you are correct, however, when I do this:
Dim lc As New ListControl
I get this error:
BC30569: 'New' cannot be used on a class that is declared 'MustInherit'.
The sub called rePopulate is fired in the page when a certain link is clicked. Up until that point there should only be an empty listcontrol in the placeholder, so it shows nothing on screen. The problem is that rePopulate is called many times during the total page execution, and each time may set the listControl to be either radio buttons or check boxes, therefore I cannot set it as a specific type in page_init - it must remain generic at that point.
Hi Rouchie,
Just try putting this line
lc.ID = "lc"
before this one ph.Controls.Add(lc)
something like
Dim lc As ListControl
lc.ID = "lc"
ph.Controls.Add(lc)
I am not very confident on this, but I am gessing that probably the control needs to have a ID before it is added to placeholder and may be that is the reason you are getting the error.
Just try this.....hope it helps!
Harshit Sheth
Just try putting this line
lc.ID = "lc"
before this one ph.Controls.Add(lc)
something like
Dim lc As ListControl
lc.ID = "lc"
ph.Controls.Add(lc)
I am not very confident on this, but I am gessing that probably the control needs to have a ID before it is added to placeholder and may be that is the reason you are getting the error.
Just try this.....hope it helps!
Harshit Sheth
ASKER
Thanks again Harshit, but another error is thrown:
Object reference not set to an instance of an object.
lc.ID = "lc"
Object reference not set to an instance of an object.
lc.ID = "lc"
Rouchie,
I got think I got what you are trying to do now.
First of all you are creating the controls dynamycally, so there is no need to add the contorls in the placeholder in the Page_Init block. The code which you have written in the "Page_Init" block should be written in the "Sub rePopulate" immegiately after the controls are initialzed using the "New".
The reason being that the control is created dynamically in the "Sub rePopulate" and while you are trying to add it in the "Page_Init" block where the instance of the control is not yet created.
So here is what you can do
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lc As ListControl
End Sub
Sub rePopulate(ByVal aNumber As Boolean) ' called later in the page
Dim answers As ListControl = CType(ph.FindControl("lc") , ListControl)
answers.Items.Clear()
If aNumber Then
answers = New RadioButtonList
Else
answers = New CheckBoxList
End If
lc.ID = "lc"
ph.Controls.Add(lc)
..... ' populate list items ....
End Sub
I got think I got what you are trying to do now.
First of all you are creating the controls dynamycally, so there is no need to add the contorls in the placeholder in the Page_Init block. The code which you have written in the "Page_Init" block should be written in the "Sub rePopulate" immegiately after the controls are initialzed using the "New".
The reason being that the control is created dynamically in the "Sub rePopulate" and while you are trying to add it in the "Page_Init" block where the instance of the control is not yet created.
So here is what you can do
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lc As ListControl
End Sub
Sub rePopulate(ByVal aNumber As Boolean) ' called later in the page
Dim answers As ListControl = CType(ph.FindControl("lc")
answers.Items.Clear()
If aNumber Then
answers = New RadioButtonList
Else
answers = New CheckBoxList
End If
lc.ID = "lc"
ph.Controls.Add(lc)
..... ' populate list items ....
End Sub
ASKER
When you call rePopulate for the first time, "lc" won't be in the placeholder though will it, because it hasn't been added there yet?
Your code (if I read it correctly!) seems to reference the control within the placeholder before it's actually added.
Your code (if I read it correctly!) seems to reference the control within the placeholder before it's actually added.
Yeah, you are right; the correct code will be something like
Sub rePopulate(ByVal aNumber As Boolean) ' called later in the page
Dim answers As ListControl
If aNumber Then
answers = New RadioButtonList
Else
answers = New CheckBoxList
End If
answers .ID = "answers "
ph.Controls.Add(answers)
..... ' populate list items ....
End Sub
Also, you don’t need to define anything in Page_Init since the control is created and populated dynamically in the Sub rePopulate itself.
Harshit Sheth
Sub rePopulate(ByVal aNumber As Boolean) ' called later in the page
Dim answers As ListControl
If aNumber Then
answers = New RadioButtonList
Else
answers = New CheckBoxList
End If
answers .ID = "answers "
ph.Controls.Add(answers)
..... ' populate list items ....
End Sub
Also, you don’t need to define anything in Page_Init since the control is created and populated dynamically in the Sub rePopulate itself.
Harshit Sheth
Hey,
really sorry missed something again
make this Dim answers As ListControl
as
Dim answers As New ListControl
Harshit Sheth
really sorry missed something again
make this Dim answers As ListControl
as
Dim answers As New ListControl
Harshit Sheth
goofed up! :-)
Just ignore the last comment.....that will actually give you an object reference error again
And that should be it!!!
Harshit Sheth
Just ignore the last comment.....that will actually give you an object reference error again
And that should be it!!!
Harshit Sheth
ASKER
>> Yeah, you are right; the correct code will be something like
By declaring the list control in this sub, when the page is posted back the control isn't actually there. Here is the code that reads the values back:
Sub readChoices(...)
Dim a As ListControl
If singleChoice Then
a = CType(ph.FindControl("lc") , RadioButtonList)
Else
a = CType(ph.FindControl("lc") , CheckBoxList)
End If
For Each l As ListItem In a.Items <-- "Object reference not set to an instance of an object."
Trace.Warn(l.Selected)
choiceArray.Add(l.Selected )
Next
End Sub
>> Dim answers As New ListControl
BC30569: 'New' cannot be used on a class that is declared 'MustInherit'.
By declaring the list control in this sub, when the page is posted back the control isn't actually there. Here is the code that reads the values back:
Sub readChoices(...)
Dim a As ListControl
If singleChoice Then
a = CType(ph.FindControl("lc")
Else
a = CType(ph.FindControl("lc")
End If
For Each l As ListItem In a.Items <-- "Object reference not set to an instance of an object."
Trace.Warn(l.Selected)
choiceArray.Add(l.Selected
Next
End Sub
>> Dim answers As New ListControl
BC30569: 'New' cannot be used on a class that is declared 'MustInherit'.
ASKER
Harshit,
Our last posts seemed to arrive together. Not sure if you are still willing to help but if so I'd still be interested in getting my head around this :-)
Our last posts seemed to arrive together. Not sure if you are still willing to help but if so I'd still be interested in getting my head around this :-)
Hey Rouchie,
Always willing to help, that what I am here for! Did not post any further comment as there was no further reply from you.
Anyways, As per my last comment, Just don’t use the 'New' keyword in the line which you got an error
>Dim answers As New ListControl
>BC30569: 'New' cannot be used on a class that is declared 'MustInherit'
And then let me know how the program behaves and if possible post the modified code here once again (that is of course if its still not working!)
Harshit Sheth
Always willing to help, that what I am here for! Did not post any further comment as there was no further reply from you.
Anyways, As per my last comment, Just don’t use the 'New' keyword in the line which you got an error
>Dim answers As New ListControl
>BC30569: 'New' cannot be used on a class that is declared 'MustInherit'
And then let me know how the program behaves and if possible post the modified code here once again (that is of course if its still not working!)
Harshit Sheth
ASKER
Hi Harshit - thanks for getting back.
I've written the entire problem out in code here for you to see yourself. This saves me chopping and pasting the relevant bits.
Within the code, the list populates fine, but when the page is posted back, the FindControl fails because the list isn't actually there (I think)! Therefore I can't read the values back correctly.
<%@ Page Language="VB" Trace="true" %>
<script runat="server">
Sub createList(ByVal sender As Object, ByVal e As CommandEventArgs)
If e.CommandArgument = "single" Then
loadChoices(True)
Else
loadChoices(False)
End If
ViewState("loadChoices") = e.CommandArgument
btn_submit.Visible = True
End Sub
Sub loadChoices(ByVal singleChoice As Boolean)
Dim lc As ListControl
If singleChoice Then
lc = New RadioButtonList()
Else
lc = New CheckBoxList()
End If
lc.Items.Add(New ListItem("Value 0", 0))
lc.Items.Add(New ListItem("Value 1", 1))
lc.Items.Add(New ListItem("Value 2", 2))
ph.Controls.Add(lc)
lc.ID = "lst_choices"
End Sub
Sub readChoices(ByVal sender As Object, ByVal e As CommandEventArgs)
Dim lc As ListControl
Dim singleAnswer As String = ViewState("loadChoices")
If singleAnswer = "single" Then
lc = CType(ph.FindControl("lst_ choices"), RadioButtonList)
Else
lc = CType(ph.FindControl("lst_ choices"), CheckBoxList)
End If
For Each l As ListItem In lc.Items
Trace.Warn(l.Text & ": " & l.Selected)
Next
End Sub
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>My Page</title>
</head>
<body>
<form runat="server">
<asp:Button ID="btn1" runat="server" Text="Create Single Choice List" OnCommand="createList" CommandArgument="single" />
<asp:Button ID="btn2" runat="server" Text="Create Multi Choice List" OnCommand="createList" CommandArgument="multi" />
<asp:PlaceHolder ID="ph" runat="server" />
<asp:Button id="btn_submit" runat="server" Text="Submit" OnCommand="readChoices" Visible="false" />
</form>
</body>
</html>
I've written the entire problem out in code here for you to see yourself. This saves me chopping and pasting the relevant bits.
Within the code, the list populates fine, but when the page is posted back, the FindControl fails because the list isn't actually there (I think)! Therefore I can't read the values back correctly.
<%@ Page Language="VB" Trace="true" %>
<script runat="server">
Sub createList(ByVal sender As Object, ByVal e As CommandEventArgs)
If e.CommandArgument = "single" Then
loadChoices(True)
Else
loadChoices(False)
End If
ViewState("loadChoices") = e.CommandArgument
btn_submit.Visible = True
End Sub
Sub loadChoices(ByVal singleChoice As Boolean)
Dim lc As ListControl
If singleChoice Then
lc = New RadioButtonList()
Else
lc = New CheckBoxList()
End If
lc.Items.Add(New ListItem("Value 0", 0))
lc.Items.Add(New ListItem("Value 1", 1))
lc.Items.Add(New ListItem("Value 2", 2))
ph.Controls.Add(lc)
lc.ID = "lst_choices"
End Sub
Sub readChoices(ByVal sender As Object, ByVal e As CommandEventArgs)
Dim lc As ListControl
Dim singleAnswer As String = ViewState("loadChoices")
If singleAnswer = "single" Then
lc = CType(ph.FindControl("lst_
Else
lc = CType(ph.FindControl("lst_
End If
For Each l As ListItem In lc.Items
Trace.Warn(l.Text & ": " & l.Selected)
Next
End Sub
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>My Page</title>
</head>
<body>
<form runat="server">
<asp:Button ID="btn1" runat="server" Text="Create Single Choice List" OnCommand="createList" CommandArgument="single" />
<asp:Button ID="btn2" runat="server" Text="Create Multi Choice List" OnCommand="createList" CommandArgument="multi" />
<asp:PlaceHolder ID="ph" runat="server" />
<asp:Button id="btn_submit" runat="server" Text="Submit" OnCommand="readChoices" Visible="false" />
</form>
</body>
</html>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Right, let me crank up VWD and do a test page and I'll get back to you! :-)
ASKER
The link provided a nice way around what I'm trying to accomplish. Thanks Harshit! :-)
From code which you have given it is difficult to find out when Sub rePopulate is called and hence impossible to find the implications of the code inside the Sub.
However, I think the error which you are getting in the Page_Init function is because you have simply declared the ListControl object and not initialized it with the 'New' keyword and hence you are getting the error as " Value cannot be null."
Harshit Sheth