Dynamically Loaded Web User Control and Session State
Loading controls is a pretty easy task, and creating them at run time is pretty simple. But how about loading them dynamically inside a control or somehow adding them on your list of child controls? Ahh, ahh, ahh, think again. Maybe it's an easier task to load them dynamically but using a Web User Control was not a great idea. It almost took me two to three days scratching my head on how to load these user controls dynamically without affecting the events, postbacks, and most importantly the sessions behind it. Waah, it was challenging!
To visualize it, I have a page which consists of 2 buttons. The two buttons serve as a navigation for 2 pages which is specifically a web user controls. The first web user control consist of a button and a textbox. The button fires up the string on the Session bag which is link on the textbox. The second web user control now contains only a textbox which shows the message on the Session memory. Additionally, we want to load those user controls on a Placeholder or a Panel, or even on UpdatePanel for AJAX integration.
So the question is, why is it so complicated on a simple situation like that? Well the answer is, at page load, the page is stateless, meaning, it has no idea about the dynamically loaded controls. In other words, if you click button one which loads the first user control, it's fine and working properly, but try to fire the event inside the first user control on which you loaded dynamically. Voila! Nothing happens! As if all the controls inside the first web user control is gone. That is now the problem. You cannot even fire up an event, even a single send of data on Session State.
So what did I do? First don't initialize your control on Button1_Click, because it will unload your web user control if you click their buttons:
Protected Sub Button1_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Init
Dim ctl As Control = Page.LoadControl("Page1.ascx")
ctl.ID = "MyCTL"
PlaceHolder1.Controls.Add(ctl)
End Sub
On Button 2, you can now put it on button2 click event:
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim x As Page2 = CType(Page.LoadControl("Page2.ascx"), Page2)
PlaceHolder1.Controls.Add(x)
PlaceHolder1.Controls.Remove(ctl)
End Sub
And for the first user control, this will send the data on textbox onto Session bag:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Session("MySession") = TextBox1.Text
End Sub
And the second user control will load it on page load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Label1.Text = Session("MySession")
End Sub
Now, you can navigate to two different user controls and can still fire an event handlers from them! What do you think guys? Any suggestions? 