Solved

Trying to place a ListControl in page_init

Posted on 2006-07-07
16
449 Views
Last Modified: 2008-02-01
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)
0
Comment
Question by:Rouchie
  • 8
  • 8
16 Comments
 
LVL 3

Expert Comment

by:harshits
ID: 17057110
Hi,

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
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17057129
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.
0
 
LVL 3

Expert Comment

by:harshits
ID: 17057291
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
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17057305
Thanks again Harshit, but another error is thrown:

   Object reference not set to an instance of an object.
   lc.ID = "lc"
0
 
LVL 3

Expert Comment

by:harshits
ID: 17057491
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
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17057525
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.
0
 
LVL 3

Expert Comment

by:harshits
ID: 17057704
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
0
 
LVL 3

Expert Comment

by:harshits
ID: 17057708
Hey,

really sorry missed something again

make this Dim answers As ListControl

as

Dim answers As New ListControl

Harshit Sheth
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Expert Comment

by:harshits
ID: 17057802
goofed up! :-)

Just ignore the last comment.....that will actually give you an object reference error again

And that should be it!!!

Harshit Sheth
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17057827
>> 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'.
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17093660
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 :-)
0
 
LVL 3

Expert Comment

by:harshits
ID: 17096946
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

0
 
LVL 25

Author Comment

by:Rouchie
ID: 17097668
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>
0
 
LVL 3

Accepted Solution

by:
harshits earned 500 total points
ID: 17120327
The problem which you are facing now is a universal problem of maintaining the state of dynamically created controls.

You'll need to implement some extra logic to maintain the state of the controls between postbacks.

Here is an example of how you can do the same...

http://www.codeproject.com/aspnet/retainingstate.asp

Harshit sheth
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17120754
Right, let me crank up VWD and do a test page and I'll get back to you! :-)
0
 
LVL 25

Author Comment

by:Rouchie
ID: 17120816
The link provided a nice way around what I'm trying to accomplish.  Thanks Harshit! :-)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

In this Article, I will provide a few tips in problem and solution manner. Opening an ASPX page in Visual studio 2003 is very slow. To make it fast, please do follow below steps:   Open the Solution/Project. Right click the ASPX file to b…
In .NET 2.0, Microsoft introduced the Web Site.  This was the default way to create a web Project in Visual Studio 2005.  In Visual Studio 2008, the Web Application has been restored as the default web Project in Visual Studio/.NET 3.x The Web Si…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This video discusses moving either the default database or any database to a new volume.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now