Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > ASP .Net > ASP .Net Building Controls > Trouble with dynamically added controls

Reply
Thread Tools

Trouble with dynamically added controls

 
 
Daniel Walzenbach
Guest
Posts: n/a
 
      10-15-2003
Hi everybody,

I need to dynamically populate a webpage at runtime with controls. This is the code I wrote.



Public Class WebForm1

Inherits System.Web.UI.Page



#Region " Vom Web Form Designer generierter Code "



'Dieser Aufruf ist für den Web Form-Designer erforderlich.

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()



End Sub

Protected WithEvents PlaceHolder1 As System.Web.UI.WebControls.PlaceHolder

Protected WithEvents Button1 As System.Web.UI.WebControls.Button



'HINWEIS: Die folgende Platzhalterdeklaration ist für den Web Form-Designer erforderlich.

'Nicht löschen oder verschieben.

Private designerPlaceholderDeclaration As System.Object



Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init

'CODEGEN: Dieser Methodenaufruf ist für den Web Form-Designer erforderlich

'Verwenden Sie nicht den Code-Editor zur Bearbeitung.

InitializeComponent()

End Sub



#End Region



Private counter As System.Int32 = 0



Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' Hier Benutzercode zur Seiteninitialisierung einfügen

End Sub



Private Sub AddControls(ByVal strLabel As String)



Dim myNewLabel As New System.Web.UI.WebControls.Label



' counter to give objects different names

counter = Session.Item("Counter")

counter += 1

Session.Item("counter") = counter



myNewLabel.ID = String.Format("myNewLabel{0}", counter)

myNewLabel.Text = strLabel & CStr(counter)

' I thought that EnableViewState should be sufficient to store the controls value

myNewLabel.EnableViewState = True





' save controls for ViewState

Dim dynControls As System.Collections.ArrayList

dynControls = Viewstate.Item("dynControls")



' create new ArrayList if it does not exist

If dynControls Is Nothing Then

dynControls = New System.Collections.ArrayList

End If



'store information about control in Triplet

Dim labelTrip As New System.Web.UI.Triplet

labelTrip.First = myNewLabel.ID

labelTrip.Second = myNewLabel.GetType.ToString

labelTrip.Third = PlaceHolder1.ID

dynControls.Add(labelTrip)





' put control on Placeholder

PlaceHolder1.Controls.Add(myNewLabel)

' and save information about control in ViewState

ViewState("dynControls") = dynControls





End Sub



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

AddControls("Created From Button")



End Sub



Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)



Dim SampleAssembly As System.Reflection.Assembly




Dim t As Type

t = GetType(System.Web.UI.WebControls.Label)



SampleAssembly = System.Reflection.Assembly.Load(t.Assembly.FullNam e)



Dim dynControls As System.Collections.ArrayList

dynControls = ViewState.Item("dynControls")



If Not dynControls Is Nothing Then



' run through all saved controls

For Each obj As System.Object In dynControls

Dim ctlTrip As System.Web.UI.Triplet

ctlTrip = CType(obj, System.Web.UI.Triplet)



Dim parent As System.Web.UI.WebControls.PlaceHolder

parent = Page.FindControl(ctlTrip.Third)



Dim ctl As System.Web.UI.Control

Try

'ctl = Activator.CreateInstance(Type.GetType(ctlTrip.Seco nd, True))

ctl = Activator.CreateInstance(SampleAssembly.GetType(ct lTrip.Second, True))



Catch ex As Exception

Response.Write(ex.Message)

End Try

ctl.ID = ctlTrip.First



parent.Controls.Add(ctl)

Next



End If



End Sub



End Class



The controls get recreated in the OnLoad method but don't contain any values. I thought their values should be stored in ViewState? Does anybody know why the controls don't contain any values?



Thanks in advance

Best regards


Daniel Walzenbach

P.S. If you need to contact me simply remove ".NOSPAM" from my email address.

 
Reply With Quote
 
 
 
 
Jacob Yang [MSFT]
Guest
Posts: n/a
 
      10-16-2003
Hi Daniel,

Based on my research and experience, I would like to share the following
information with you.

At the OnLoad stage in the page lifecycle, server controls in the hierarchy
are created and initialized, view state is restored. That is, any control
created in OnLoad phrase has no chance to get its viewstate back.

Please override the OnInit method and move the creation of the controls to
this stage, for in this stage of the server control's lifecycle, the
control's view state has yet to be populated.

I hope it helps.

Best regards,

Jacob Yang
Microsoft Online Partner Support
Get Secure! ¨C www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

 
Reply With Quote
 
 
 
 
Teemu Keiski
Guest
Posts: n/a
 
      10-16-2003
Hi,

I'd like to say a few words.

First: control lifecycle is as follows:

1. Instantiate
2. Initialize
3. TrackViewState
4. LoadViewState (postback)
5. Load postback data (postback, IPostBackDatahandler.LoadPostdata)
6. Load
7. Load postback data for dynamical controls added on Page_Load
8. Raise Changed Events (postback,
IPostBackDatahandler.RaisePostDataChanged)
9. Raise postback event (postback, IPostBackEventHandler.RaisePostBackEvent)
10.PreRender
11. SaveViewState
12. Render
13. Unload
14. Dispose

Second, dynamically added control *can* load its ViewState after
LoadViewState phase. This happens "automagically" when control just is added
to the Control tree and as it is dynamical control it needs to be added on
every request. Adding control to the control tree in the same order
(position) is important because ViewState mechanism relies on control's
index in Controls collection, not for example on Controläs ID. This is for
performance reasons.

Another thing is that controls that load postback data needs to be added to
the control tree at Loads phase at ther latest during the request they do
postback data processing. That's because postback data loading is intiated
by the Page itself. With ViewState loading (when control is added), it is
the ControlCollection that handles the plumbing and therefore control can
load ViewState during the lifecycle.

More complete explanation and for simple example see:
http://www.asp.net/Forums/ShowPost.a...&PostID=250529

Thanks,
--
Teemu Keiski
MCP, Microsoft MVP (ASP.NET), AspInsiders member
ASP.NET Forum Moderator, AspAlliance Columnist

"Jacob Yang [MSFT]" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi Daniel,
>
> Based on my research and experience, I would like to share the following
> information with you.
>
> At the OnLoad stage in the page lifecycle, server controls in the

hierarchy
> are created and initialized, view state is restored. That is, any control
> created in OnLoad phrase has no chance to get its viewstate back.
>
> Please override the OnInit method and move the creation of the controls to
> this stage, for in this stage of the server control's lifecycle, the
> control's view state has yet to be populated.
>
> I hope it helps.
>
> Best regards,
>
> Jacob Yang
> Microsoft Online Partner Support
> Get Secure! ¨C www.microsoft.com/security
> This posting is provided "as is" with no warranties and confers no rights.
>



 
Reply With Quote
 
Jacob Yang [MSFT]
Guest
Posts: n/a
 
      10-17-2003
Hi Daniel,

Firstly I want to thank Teemu's great help on this issue. Please refer to
his response carefully.

From your code snippet, I am not sure how you assign the values to those
dynamical controls.

The postback data processing and the viewstate restore were done
automatically by page in each request.

One important thing is that those dynamical controls should be added to the
control tree in the same order in each request, including the first
request. Otherwise, the viewstate will fail to work.

Please try the following code, checking whether it works fine,

1. Create a new ASP.NET (VB.NET) app,
2. Webform1.aspx will be added be default.
3. Drap and drop a button onto the web from.
4. Copy the following code into the Page_Load event.

'Put user code to initialize the page here
Dim l As Label = New Label
Page.Controls(1).Controls.Add(l)

Dim txt As TextBox = New TextBox
Page.Controls(1).Controls.Add(txt)

If (Not IsPostBack) Then
l.Text = "Set on initial request"
End If

5. Compile and browse the webform1.aspx.
6. Type any chars into the textbox that was added dynamically.
7. Click the button to submit the webform. When the submit completed, you
should see the value you typed in the textbox should persist, and also the
text of the Label control should also be there.

Please try it and let me know the result.

Best regards,

Jacob Yang
Microsoft Online Partner Support
Get Secure! ¨C www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

 
Reply With Quote
 
Daniel Walzenbach
Guest
Posts: n/a
 
      10-18-2003
Hi Jacob,



Well, your example worked perfectly well which makes it more wired form e as
I thought I made exactly the same thing. I mean there must be a difference
otherwise it would work but I can't see it. As it is late by now I'll look
over it tomorrow in a more pronounced way.



Thank you for your help! The code you gave me is a good basis for a start
At least I know by now what does work.



Daniel





"Jacob Yang [MSFT]" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> Hi Daniel,
>
> Firstly I want to thank Teemu's great help on this issue. Please refer to
> his response carefully.
>
> From your code snippet, I am not sure how you assign the values to those
> dynamical controls.
>
> The postback data processing and the viewstate restore were done
> automatically by page in each request.
>
> One important thing is that those dynamical controls should be added to

the
> control tree in the same order in each request, including the first
> request. Otherwise, the viewstate will fail to work.
>
> Please try the following code, checking whether it works fine,
>
> 1. Create a new ASP.NET (VB.NET) app,
> 2. Webform1.aspx will be added be default.
> 3. Drap and drop a button onto the web from.
> 4. Copy the following code into the Page_Load event.
>
> 'Put user code to initialize the page here
> Dim l As Label = New Label
> Page.Controls(1).Controls.Add(l)
>
> Dim txt As TextBox = New TextBox
> Page.Controls(1).Controls.Add(txt)
>
> If (Not IsPostBack) Then
> l.Text = "Set on initial request"
> End If
>
> 5. Compile and browse the webform1.aspx.
> 6. Type any chars into the textbox that was added dynamically.
> 7. Click the button to submit the webform. When the submit completed, you
> should see the value you typed in the textbox should persist, and also the
> text of the Label control should also be there.
>
> Please try it and let me know the result.
>
> Best regards,
>
> Jacob Yang
> Microsoft Online Partner Support
> Get Secure! ¨C www.microsoft.com/security
> This posting is provided "as is" with no warranties and confers no rights.
>



 
Reply With Quote
 
Daniel Walzenbach
Guest
Posts: n/a
 
      10-19-2003
Well. I finally got it to work. Thanks to everybody who helped me. If you
are interested how to dynamically create controls on a website on click and
preserve their ViewState here your go:



Your aspx site should look something like this:



<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb"
Inherits="DynamicControlsAdd.WebForm1" trace = true %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<title>WebForm1</title>

<meta content="Microsoft Visual Studio .NET 7.1"
name="GENERATOR">

<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">

<meta content="JavaScript" name="vs_defaultClientScript">

<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">

</HEAD>

<body>

<form id="Form1" method="post" runat="server">

<asplaceholder id="myPlaceHolder"
runat="server"></asplaceholder><BR>

<BR>

<BR>

<asp:button id="btnAddTextBox" runat="server" Text="Add
Textbox"></asp:button>

</form>

</body>

</HTML>



And here is the code behind:



Public Class WebForm1

Inherits System.Web.UI.Page



#Region " Vom Web Form Designer generierter Code "



'Dieser Aufruf ist für den Web Form-Designer erforderlich.

<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()



End Sub

Protected WithEvents myPlaceHolder As
System.Web.UI.WebControls.PlaceHolder

Protected WithEvents btnAddTextBox As System.Web.UI.WebControls.Button



'HINWEIS: Die folgende Platzhalterdeklaration ist für den Web
Form-Designer erforderlich.

'Nicht löschen oder verschieben.

Private designerPlaceholderDeclaration As System.Object



Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init

'CODEGEN: Dieser Methodenaufruf ist für den Web Form-Designer
erforderlich

'Verwenden Sie nicht den Code-Editor zur Bearbeitung.

InitializeComponent()

End Sub



#End Region



Private counter As System.Int32 = 0



Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

' Hier Benutzercode zur Seiteninitialisierung einfügen

InitPage()

End Sub



Private Sub AddControls(ByVal strLabel As String)



Dim myNewTextBox As New System.Web.UI.WebControls.TextBox



' counter to give objects different names

counter = Session.Item("Counter")

counter += 1

Session.Item("counter") = counter



myNewTextBox.ID = String.Format("myNewTextBox{0}", counter)

myNewTextBox.Text = strLabel & CStr(counter)

myNewTextBox.EnableViewState = True





' save controls for SessionState

Dim dynControls As System.Collections.ArrayList

dynControls = Session.Item("dynControls")



' create new ArrayList if it does not exist

If dynControls Is Nothing Then

dynControls = New System.Collections.ArrayList

End If



'store information about control in Triplet

Dim ControlTrip As New System.Web.UI.Triplet

ControlTrip.First = myNewTextBox.ID

ControlTrip.Second = myNewTextBox.GetType.ToString

ControlTrip.Third = myPlaceHolder.ID

dynControls.Add(ControlTrip)





' put control on Placeholder

myPlaceHolder.Controls.Add(myNewTextBox)

' and save information about control in SessionState

Session.Item("dynControls") = dynControls



End Sub



Private Sub btnAddTextBox_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnAddTextBox.Click

AddControls("Created From Button")



End Sub



Private Sub InitPage()

Dim SampleAssembly As System.Reflection.Assembly



' Load the assembly by providing the type name. Needs to be done
to instanciate the control

' with "CreateInstance" which needs a fully qualified name

Dim t As Type

t = GetType(System.Web.UI.WebControls.Label)



SampleAssembly =
System.Reflection.Assembly.Load(t.Assembly.FullNam e)



Dim dynControls As System.Collections.ArrayList

dynControls = Session.Item("dynControls")



If Not dynControls Is Nothing Then



Dim myEnumerator As IEnumerator

myEnumerator = dynControls.GetEnumerator



' run through all saved controls

While myEnumerator.MoveNext

Dim ctlTrip As System.Web.UI.Triplet



' restore Triplet containing informations about the
control

ctlTrip = CType(myEnumerator.Current,
System.Web.UI.Triplet)



Dim myPlaceHolder As
System.Web.UI.WebControls.PlaceHolder

myPlaceHolder = Page.FindControl(ctlTrip.Third)



Dim ctl As System.Web.UI.Control

Try

ctl =
Activator.CreateInstance(SampleAssembly.GetType(ct lTrip.Second, True))

ctl.ID = ctlTrip.First



Catch ex As Exception

Response.Write(ex.Message)

End Try



myPlaceHolder.Controls.Add(ctl)



End While



End If

End Sub



End Class



Thank you again Jacob and Teemu for your help!

Best regards


Daniel Walzenbach

P.S. If you need to contact me simply remove ".NOSPAM" from my email address



"Daniel Walzenbach" <(E-Mail Removed)> schrieb im
Newsbeitrag news:(E-Mail Removed)...
> Hi Jacob,
>
>
>
> Well, your example worked perfectly well which makes it more wired form e

as
> I thought I made exactly the same thing. I mean there must be a difference
> otherwise it would work but I can't see it. As it is late by now I'll look
> over it tomorrow in a more pronounced way.
>
>
>
> Thank you for your help! The code you gave me is a good basis for a start
> At least I know by now what does work.
>
>
>
> Daniel
>
>
>
>
>
> "Jacob Yang [MSFT]" <(E-Mail Removed)> schrieb im Newsbeitrag
> news:(E-Mail Removed)...
> > Hi Daniel,
> >
> > Firstly I want to thank Teemu's great help on this issue. Please refer

to
> > his response carefully.
> >
> > From your code snippet, I am not sure how you assign the values to those
> > dynamical controls.
> >
> > The postback data processing and the viewstate restore were done
> > automatically by page in each request.
> >
> > One important thing is that those dynamical controls should be added to

> the
> > control tree in the same order in each request, including the first
> > request. Otherwise, the viewstate will fail to work.
> >
> > Please try the following code, checking whether it works fine,
> >
> > 1. Create a new ASP.NET (VB.NET) app,
> > 2. Webform1.aspx will be added be default.
> > 3. Drap and drop a button onto the web from.
> > 4. Copy the following code into the Page_Load event.
> >
> > 'Put user code to initialize the page here
> > Dim l As Label = New Label
> > Page.Controls(1).Controls.Add(l)
> >
> > Dim txt As TextBox = New TextBox
> > Page.Controls(1).Controls.Add(txt)
> >
> > If (Not IsPostBack) Then
> > l.Text = "Set on initial request"
> > End If
> >
> > 5. Compile and browse the webform1.aspx.
> > 6. Type any chars into the textbox that was added dynamically.
> > 7. Click the button to submit the webform. When the submit completed,

you
> > should see the value you typed in the textbox should persist, and also

the
> > text of the Label control should also be there.
> >
> > Please try it and let me know the result.
> >
> > Best regards,
> >
> > Jacob Yang
> > Microsoft Online Partner Support
> > Get Secure! ¨C www.microsoft.com/security
> > This posting is provided "as is" with no warranties and confers no

rights.
> >

>
>



 
Reply With Quote
 
Jacob Yang [MSFT]
Guest
Posts: n/a
 
      10-20-2003
Hi Daniel,

Congratulations!

I am very glad to know that the problem is resolved. Thank you for sharing
your resolution. It is helpful to everybody here.

Best regards,

Jacob Yang
Microsoft Online Partner Support
Get Secure! ¨C www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Data and controls from dynamically added controls is rmoved on Submit David Hubbard ASP .Net 2 01-17-2006 06:52 PM
Inserting Controls Dynamically - with Validators Also Added Dynamically Jeffrey Todd ASP .Net 1 06-02-2005 04:33 PM
existing controls overlaying dynamically added controls ENathan ASP .Net Web Controls 2 01-10-2005 10:34 PM
newbie: Dynamically added controls are lost after postback NotYetaNurd ASP .Net 1 11-07-2003 01:31 PM
Positioning Dynamically added controls Harry ASP .Net 1 06-25-2003 06:08 AM



Advertisments