Hi,
been a while since I posted a question myself instead of trying to help
others out.
I'm refactoring an existing web app that uses dynamic loading of user
controls and a lot of response.redire cts to the same page. Because I hate
the overhead by doing this I'm searching for a cleaner option.
But I'm having troubles (off course or I wouldn't be posting this).
The code itself looks ok but when I do a little testing I don't get the
results as I would expect:
test scenario:
- load the page and the first uc will appear, I can type something in the
textbox and clicking the "First button" I get my textbox entry in the label.
Still good.
- when hitting the button "Load other control" I can clearly see that
AttachUC gets called the first time and loads in the first uc and goes to
the buttonevent on the FirstUC. The session gets updated in the method
Button2_Click of FirstUC and the AttachUC is called again. _dyn.ControlNam e
is "SecondUC.a scx" so that is still good. But when the page renders I still
get to see FirstUC on the page.
- After clicking the "Load other control" for the second time the correct
control gets loaded but I see that the text of the TextBox and Label of
FirstUC is set to the textbox and label of SecondUC.ascx.
Well, if someone knows a good explanation for this problem you can always
reply to this post. I'll be also looking at the problem.
This is my code so far:
default.aspx:
<%@ Page Language="vb" AutoEventWireup ="false" Codebehind="def ault.aspx.vb"
Inherits="dynam iccontrolsloadi ngandunloading. _default" trace="True"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>defaul t</title>
<meta name="GENERATOR " content="Micros oft Visual Studio .NET 7.1">
<meta name="CODE_LANG UAGE" content="Visual Basic .NET 7.1">
<meta name="vs_defaul tClientScript" content="JavaSc ript">
<meta name="vs_target Schema"
content="http://schemas.microso ft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<P>
<asp:Label id="LabelErrorM essage" runat="server"> </asp:Label></P>
<P>
<asp:PlaceHolde r id="PlaceHolder Test"
runat="server"> </asp:PlaceHolder ></P>
</form>
</body>
</HTML>
----------------------------------------------------------------------------
-----------------------
default.aspx.vb :
Public Class _default
Inherits System.Web.UI.P age
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnos tics.DebuggerSt epThrough()> Private Sub
InitializeCompo nent()
End Sub
Protected WithEvents PlaceHolderTest As
System.Web.UI.W ebControls.Plac eHolder
Protected WithEvents LabelErrorMessa ge As
System.Web.UI.W ebControls.Labe l
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceho lderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeCompo nent()
End Sub
#End Region
Private _dyn As DynaKeeper
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
Session("dynake ep") = New DynaKeeper("Pla ceHolderTest",
"FirstUC.as cx", AddressOf Me.AttachUC)
End If
_dyn = DirectCast(Sess ion("dynakeep") , DynaKeeper)
LabelErrorMessa ge.Text = _dyn.ControlNam e + " - " +
_dyn.PlaceHolde rName + " - " + _dyn.CallBackMe thod.ToString
AttachUC()
End Sub
Private Sub AttachUC()
Try
If Not IsNothing(Sessi on("dynakeep") ) Then
Dim holder As PlaceHolder =
DirectCast(Me.F indControl(_dyn .PlaceHolderNam e), PlaceHolder)
holder.Controls .Clear()
holder.Controls .Add(LoadContro l(_dyn.ControlN ame))
End If
Catch ex As Exception
LabelErrorMessa ge.Text = ex.Message
End Try
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
FirstUC.ascx:
<%@ Control Language="vb" AutoEventWireup ="false"
Codebehind="Fir stUC.ascx.vb"
Inherits="dynam iccontrolsloadi ngandunloading. FirstUC"
TargetSchema="h ttp://schemas.microso ft.com/intellisense/ie5" %>
<P>
<asp:TextBox id="TextBox1" runat="server"> </asp:TextBox>
<asp:Button id="Button1" runat="server" Text="First Go"></asp:Button>
<asp:Label id="Label1" runat="server"> </asp:Label></P>
<P>
<asp:Button id="Button2" runat="server" Text="Load other
control"></asp:Button></P>
----------------------------------------------------------------------------
-----------------------
FirstUC.ascx.vb :
Public Class FirstUC
Inherits System.Web.UI.U serControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnos tics.DebuggerSt epThrough()> Private Sub
InitializeCompo nent()
End Sub
Protected WithEvents TextBox1 As System.Web.UI.W ebControls.Text Box
Protected WithEvents Button1 As System.Web.UI.W ebControls.Butt on
Protected WithEvents Label1 As System.Web.UI.W ebControls.Labe l
Protected WithEvents Button2 As System.Web.UI.W ebControls.Butt on
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceho lderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeCompo nent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
Label1.Text = "First user control loaded"
End If
End Sub
Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button1.Click
Label1.Text = TextBox1.Text.T rim
End Sub
Private Sub Button2_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button2.Click
If Not IsNothing(Sessi on("dynakeep") ) Then
Dim dyn As DynaKeeper = DirectCast(Sess ion("dynakeep") ,
DynaKeeper)
dyn.ControlName = "SecondUC.a scx"
dyn.CallBackMet hod.Invoke()
End If
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
Second.ascx:
<%@ Control Language="vb" AutoEventWireup ="false"
Codebehind="Sec ondUC.ascx.vb"
Inherits="dynam iccontrolsloadi ngandunloading. SecondUC"
TargetSchema="h ttp://schemas.microso ft.com/intellisense/ie5" %>
<P>
<asp:TextBox id="TextBox1" runat="server"> </asp:TextBox></P>
<P> </P>
<P>
<asp:Button id="Button1" runat="server" Text="Second Go"></asp:Button></P>
<P>
<asp:Label id="Label1" runat="server"> </asp:Label></P>
----------------------------------------------------------------------------
-----------------------
SecondUC.ascx.v b:
Public Class SecondUC
Inherits System.Web.UI.U serControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnos tics.DebuggerSt epThrough()> Private Sub
InitializeCompo nent()
End Sub
Protected WithEvents TextBox1 As System.Web.UI.W ebControls.Text Box
Protected WithEvents Button1 As System.Web.UI.W ebControls.Butt on
Protected WithEvents Label1 As System.Web.UI.W ebControls.Labe l
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceho lderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeCompo nent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
Label1.Text = "Second user control loaded"
End If
End Sub
Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button1.Click
Label1.Text = TextBox1.Text.T rim
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
DynaKeeper.vb:
Public Class DynaKeeper
Private _placeHolderNam e As String
Private _controlName As String
Private _callBack As CallBackMethodD elegate
Public Delegate Sub CallBackMethodD elegate()
Public Sub New(ByVal placeHolderName As String, ByVal controlName As
String, ByVal callBack As CallBackMethodD elegate)
_placeHolderNam e = placeHolderName
_controlName = controlName
_callBack = callBack
End Sub
Public Property PlaceHolderName () As String
Get
Return _placeHolderNam e
End Get
Set(ByVal Value As String)
_placeHolderNam e = Value
End Set
End Property
Public Property ControlName() As String
Get
Return _controlName
End Get
Set(ByVal Value As String)
_controlName = Value
End Set
End Property
Public Property CallBackMethod( ) As CallBackMethodD elegate
Get
Return _callBack
End Get
Set(ByVal Value As CallBackMethodD elegate)
_callBack = Value
End Set
End Property
End Class