Custom control created dynamically unable to handle events in PostBack

I have a user control that is dynamically loaded onto a page using the following code in the Init page.

Dim oCtl As Object oCtl = LoadControl("~/Controls/UserControl1.ascx") oCtl.Id = "UserControl11" PlaceHolder1.Controls.Clear() PlaceHolder1.Controls.Add(oCtl) 

The user control also contains a button, and I cannot capture the click of a button inside the user control.

+6
dynamic user-controls postback
source share
9 answers

There are a few things you do that are not needed and are likely to cause problems.

It:

  • There is no need to store the management object in the session. The control itself should use ViewState and Session State to store information as necessary, and not the entire instance.
  • You should not check PostBack when creating a control. It must be created every time to allow ViewState to work, and the event must be connected.
  • Controls loaded after loading ViewState often have problems working correctly, so if possible, avoid loading while loading the page.

This code works for me:


Default.aspx

 <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Test_User_Control._Default" %> <!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></title></head> <body> <form id="form1" runat="server"> <asp:PlaceHolder ID="PlaceHolder1" runat="server" /> </form> </body> </html> 

Default.aspx.vb

 Partial Public Class _Default Inherits System.Web.UI.Page Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init Dim control As Control = LoadControl("~/UserControl1.ascx") PlaceHolder1.Controls.Add(control) End Sub End Class 

UserControl1.ascx

 <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UserControl1.ascx.vb" Inherits="Test_User_Control.UserControl1" %> <asp:Label ID="Label1" Text="Before Button Press" runat="server" /> <asp:Button ID="Button1" Text="Push me" runat="server" /> 

UserControl1.ascx.vb

 Public Partial Class UserControl1 Inherits System.Web.UI.UserControl Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Label1.Text = "The button has been pressed!" End Sub End Class 

+10
source share

You must make sure that the control exists on the page before .NET, which is part of the "Process reverse transaction" phase of the page life cycle. Since the control is added dynamically, you need to make sure that on each post back you recreate this control so that it can find the control to fire the event.

+5
source share

Make sure you load the control on every postback β€” if the control is not in the control tree when the page returns, ASP.NET will not raise a button click event.

+3
source share

I just experienced a similar problem like you, except in my case I did not use a session to store the control.

In my case, I found the problem in this line:

PlaceHolder1.Controls.Clear()

As a result, I created child controls and added them to the parent container on the page_Init, then processed some event handlers, and after that on Page_PreRender I again put together the entire list with the updated data.

The solution I used in this case was to create a management collection once - at an early stage in the page loop.

+2
source share

A few questions:

  • At what point in the page life cycle do you load the control?
  • Where is the event handler code? In control or are you trying to connect it to the page?
  • What have you done so far to relate the event?

Finally, .Net style guidelines specifically recommend using any warts with urugian prefixes, such as o in oCtl, and you should enter it as a control, not an object.

+1
source share

Here is the full page code

 Partial Class DynamicLoad Inherits System.Web.UI.Page Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init If IsPostBack Then If Not (Session("ctl") Is Nothing) Then Dim oCtl As Object oCtl = Session("ctl") PlaceHolder1.Controls.Add(oCtl) End If End If End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Dim oCtl As Object oCtl = LoadControl("~/Controls/UserControl1.ascx") oCtl.Id = "UserControl11" PlaceHolder1.Controls.Clear() PlaceHolder1.Controls.Add(oCtl) Session("ctl") = oCtl End If End Sub End Class 

Here is the complete code for the Control user

 Partial Class UserControl1 Inherits System.Web.UI.UserControl Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Label1.Text = "This is Text AFTER Post Back in User Control 1" End Sub End Class 
0
source share

As you asked, I would write your init event this way. I will leave the Load event as an exercise:

 Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init If IsPostBack AndAlso Session("ctl") IsNot Nothing Then Dim MyControl As Control = Session("ctl") PlaceHolder1.Controls.Add(MyControl) End If End Sub 

I would also get a better name than "mycontrol", but since I don't know what this control will do.

0
source share

I don’t know, not trying to do this, but what if you programmatically connect a button event handler? For example, in the code for the user control itself in Init or Load (not sure):

 AddHandler Button1.Click, AddressOf Button1_Click 

If this does nothing, I know that it is less efficient, but what if you do not store the User Control instance in the session and always recreate it in Page_Init every time?

0
source share

You only want to load the control, if not isPostBack

-one
source share

All Articles