K
Kris van der Mast
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.redirects 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.ControlName
is "SecondUC.ascx" 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="default.aspx.vb"
Inherits="dynamiccontrolsloadingandunloading._default" trace="True"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>default</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<P>
<asp:Label id="LabelErrorMessage" runat="server"></asp:Label></P>
<P>
<asp
laceHolder id="PlaceHolderTest"
runat="server"></asp
laceHolder></P>
</form>
</body>
</HTML>
----------------------------------------------------------------------------
-----------------------
default.aspx.vb:
Public Class _default
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents PlaceHolderTest As
System.Web.UI.WebControls.PlaceHolder
Protected WithEvents LabelErrorMessage As
System.Web.UI.WebControls.Label
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private _dyn As DynaKeeper
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
Session("dynakeep") = New DynaKeeper("PlaceHolderTest",
"FirstUC.ascx", AddressOf Me.AttachUC)
End If
_dyn = DirectCast(Session("dynakeep"), DynaKeeper)
LabelErrorMessage.Text = _dyn.ControlName + " - " +
_dyn.PlaceHolderName + " - " + _dyn.CallBackMethod.ToString
AttachUC()
End Sub
Private Sub AttachUC()
Try
If Not IsNothing(Session("dynakeep")) Then
Dim holder As PlaceHolder =
DirectCast(Me.FindControl(_dyn.PlaceHolderName), PlaceHolder)
holder.Controls.Clear()
holder.Controls.Add(LoadControl(_dyn.ControlName))
End If
Catch ex As Exception
LabelErrorMessage.Text = ex.Message
End Try
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
FirstUC.ascx:
<%@ Control Language="vb" AutoEventWireup="false"
Codebehind="FirstUC.ascx.vb"
Inherits="dynamiccontrolsloadingandunloading.FirstUC"
TargetSchema="http://schemas.microsoft.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.UserControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Label1 As System.Web.UI.WebControls.Label
Protected WithEvents Button2 As System.Web.UI.WebControls.Button
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) 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(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Label1.Text = TextBox1.Text.Trim
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
If Not IsNothing(Session("dynakeep")) Then
Dim dyn As DynaKeeper = DirectCast(Session("dynakeep"),
DynaKeeper)
dyn.ControlName = "SecondUC.ascx"
dyn.CallBackMethod.Invoke()
End If
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
Second.ascx:
<%@ Control Language="vb" AutoEventWireup="false"
Codebehind="SecondUC.ascx.vb"
Inherits="dynamiccontrolsloadingandunloading.SecondUC"
TargetSchema="http://schemas.microsoft.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.vb:
Public Class SecondUC
Inherits System.Web.UI.UserControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Label1 As System.Web.UI.WebControls.Label
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) 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(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Label1.Text = TextBox1.Text.Trim
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
DynaKeeper.vb:
Public Class DynaKeeper
Private _placeHolderName As String
Private _controlName As String
Private _callBack As CallBackMethodDelegate
Public Delegate Sub CallBackMethodDelegate()
Public Sub New(ByVal placeHolderName As String, ByVal controlName As
String, ByVal callBack As CallBackMethodDelegate)
_placeHolderName = placeHolderName
_controlName = controlName
_callBack = callBack
End Sub
Public Property PlaceHolderName() As String
Get
Return _placeHolderName
End Get
Set(ByVal Value As String)
_placeHolderName = 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 CallBackMethodDelegate
Get
Return _callBack
End Get
Set(ByVal Value As CallBackMethodDelegate)
_callBack = Value
End Set
End Property
End Class
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.redirects 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.ControlName
is "SecondUC.ascx" 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="default.aspx.vb"
Inherits="dynamiccontrolsloadingandunloading._default" trace="True"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>default</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<P>
<asp:Label id="LabelErrorMessage" runat="server"></asp:Label></P>
<P>
<asp

runat="server"></asp

</form>
</body>
</HTML>
----------------------------------------------------------------------------
-----------------------
default.aspx.vb:
Public Class _default
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents PlaceHolderTest As
System.Web.UI.WebControls.PlaceHolder
Protected WithEvents LabelErrorMessage As
System.Web.UI.WebControls.Label
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private _dyn As DynaKeeper
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
Session("dynakeep") = New DynaKeeper("PlaceHolderTest",
"FirstUC.ascx", AddressOf Me.AttachUC)
End If
_dyn = DirectCast(Session("dynakeep"), DynaKeeper)
LabelErrorMessage.Text = _dyn.ControlName + " - " +
_dyn.PlaceHolderName + " - " + _dyn.CallBackMethod.ToString
AttachUC()
End Sub
Private Sub AttachUC()
Try
If Not IsNothing(Session("dynakeep")) Then
Dim holder As PlaceHolder =
DirectCast(Me.FindControl(_dyn.PlaceHolderName), PlaceHolder)
holder.Controls.Clear()
holder.Controls.Add(LoadControl(_dyn.ControlName))
End If
Catch ex As Exception
LabelErrorMessage.Text = ex.Message
End Try
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
FirstUC.ascx:
<%@ Control Language="vb" AutoEventWireup="false"
Codebehind="FirstUC.ascx.vb"
Inherits="dynamiccontrolsloadingandunloading.FirstUC"
TargetSchema="http://schemas.microsoft.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.UserControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Label1 As System.Web.UI.WebControls.Label
Protected WithEvents Button2 As System.Web.UI.WebControls.Button
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) 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(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Label1.Text = TextBox1.Text.Trim
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
If Not IsNothing(Session("dynakeep")) Then
Dim dyn As DynaKeeper = DirectCast(Session("dynakeep"),
DynaKeeper)
dyn.ControlName = "SecondUC.ascx"
dyn.CallBackMethod.Invoke()
End If
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
Second.ascx:
<%@ Control Language="vb" AutoEventWireup="false"
Codebehind="SecondUC.ascx.vb"
Inherits="dynamiccontrolsloadingandunloading.SecondUC"
TargetSchema="http://schemas.microsoft.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.vb:
Public Class SecondUC
Inherits System.Web.UI.UserControl
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Label1 As System.Web.UI.WebControls.Label
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) 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(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Label1.Text = TextBox1.Text.Trim
End Sub
End Class
----------------------------------------------------------------------------
-----------------------
DynaKeeper.vb:
Public Class DynaKeeper
Private _placeHolderName As String
Private _controlName As String
Private _callBack As CallBackMethodDelegate
Public Delegate Sub CallBackMethodDelegate()
Public Sub New(ByVal placeHolderName As String, ByVal controlName As
String, ByVal callBack As CallBackMethodDelegate)
_placeHolderName = placeHolderName
_controlName = controlName
_callBack = callBack
End Sub
Public Property PlaceHolderName() As String
Get
Return _placeHolderName
End Get
Set(ByVal Value As String)
_placeHolderName = 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 CallBackMethodDelegate
Get
Return _callBack
End Get
Set(ByVal Value As CallBackMethodDelegate)
_callBack = Value
End Set
End Property
End Class