Why is my user control not instanciated on a postback? - asp.net

I'd like to set the trigger of an UpdatePanel to a user control outside the UpdatePanel on the same page . The user control is added at design time, not at runtime.
If I statically declare the trigger, I get an error "A control with ID 'xx' cannot be found for the trigger in UpdatePanel". I tried to add the trigger at runtime in Page_Init or Page_Load, but it fails with the user control being null, although it has ViewState enabled. Has someone an idea on how to solve this?
Here is the code of the user control:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ComponentDropDownControl.ascx.cs" Inherits="ComponentDropDownControl" EnableViewState="true" %>
<asp:DropDownList ID="ComponentDropDown" runat="server" DataSourceID="ComponentFile"
DataTextField="name" DataValueField="name" OnSelectedIndexChanged="ComponentDropDown_SelectedIndexChanged" AutoPostBack="True" EnableTheming="True">
</asp:DropDownList><asp:XmlDataSource ID="ComponentFile" runat="server" DataFile="~/App_Data/Components.xml" XPath="//component"></asp:XmlDataSource>
And here it is in the aspx page:
<%# Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="create.aspx.cs" Inherits="create" Title="Create task" %>
<%# Register Src="ComponentDropDownControl.ascx" TagName="ComponentDropDownControl"
TagPrefix="uc1" %>
...
<uc1:ComponentDropDownControl ID="CustomComponentDropDown" runat="server" EnableViewState="true" />
In the Page_Load function of the aspx page, the following lines work at first time, but fail on the first PostBack (line 2, CustomComponentDropDown is null).
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = CustomComponentDropDown.UniqueID.ToString();
UpdatePanel1.Triggers.Add(trigger);
EDIT: user control is not instanciated because it is cached. In fact, it seems impossible to have a user control being both cached and able to handle events. I must be missing something because that seems pretty shitty behavior to me.
If anyone knows what I'm'doing wrong, please tell.

In what scenario would you want to handle events and have the control cached? The only reason I see to handle events is either to change internal state, or change the display state. In either case, caching will remove that possibility.

Did you register the Control as a async postback control?
ScriptManager1.RegisterAsyncPostBackControl(CustomComponentDropDown);
Also, shouldn't
trigger.ControlID = CustomComponentDropDown.UniqueID.ToString();
Simply be
trigger.ControlID = CustomComponentDropDown.ID;

Related

textbox's value not correct when displayed in browser

I have a simple textbox on my page with an embedded code block where I set its value. But in the browser it still displays "oldvalue". Can't figure out why..
<asp:TextBox id="textBox" runat="server" Text="oldvalue">
</asp:TextBox>
<%
var box = FindControl("textBox") as TextBox;
box.Text = "newvalue";
%>
This will not work as the inline expressions <% %> are executed after prerender event in the asp.net page life cycle.
And the last changes you can make to the contents of the page or its controls is upto PreRender event, So that any changes in the view state of the server control can be saved during this event. MSDN reference here.
So, rather than using inline expressions, use any event upto PreRender events of Page life cycle in your code to change the TextBox.Text property.

Parent Page Load Event fires every time a User Control Event Fires

I have an .aspx page that dynamically creates multiple user controls, each of which have their own code behind which fires based on several events at the user control level. The problem is, before the events fire in a particular user control, the parent page Load method fires as well. Because each of the controls are added dynamically, this isn't a trivial amount of processing since each control must be re-added.
I'd like to be able to fire UserControl events without forcing an update on the page that hosts it. I've tried putting the entire user control in an UpdatePanel, but postbacks within the user control still force a page load for the parent.
Here's some test code with certain parts omitted and the control added declaratively, instead of programmatically.
.ASPX Parent Page
<%# Page Language="vb" CodeBehind="MyParent.aspx.vb" %>
<%# Register TagPrefix="uc" TagName="Control" Src="MyControl.ascx" %>
<form id="form1" runat="server">
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<uc:Control ID="Control1" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
.ASCX User Control
<%# Control Language="vb" CodeBehind="MyControl.ascx.vb" %>
<p>Control Added</p>
<asp:Button runat="server" Text="ForcePostBack"/>
This is how the ASP.NET WebForms page life-cycle works. Controls that postback will cause the host (read: parent) page to go through its Page_Load. If you do not like this model, then you should consider ASP.NET MVC or a client-side solution where you can make AJAX calls to acquire data and then do client-side rendering via templating logic.
Can you avoid it by having a Session variable like 'IsFirstLoad', then render the UCs only when IsFirstLoad is null (or true)?
Also, I've found that items rendered in Page_Init dynamically will persist through PostBack, so you wouldn't have to re-render. Don't know if that applies to UCs or not, though.

Using AjaxControlToolkit Accordion control in User control that dynamically added to page in asp.net

Hi I am trying to use AjaxControlToolkit's Accordion control in user control. That user control is added to page dynamically from code behind. My code for user control is as follows:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs"
Inherits="Project.UC.Control" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
TagPrefix="asp" %>
<asp:Accordion ID="Accordion1" runat="server" HeaderSelectedCssClass="Sel"
HeaderCssClass="unSel" SelectedIndex="0">
<Panes>
<asp:AccordionPane runat="server" ID="AccordionPane1">
<Header>Red Orchid</Header>
<Content>Some content here.</Content>
</asp:AccordionPane>
</Panes>
</asp:Accordion>
To add user control dynamically I used following code in my page's code behind
Control mycontrol = this.LoadControl("~/myUserControl.ascx");
this.Controls.Add(mycontrol);
On my user control consumer page I have form tag with runat="server" also added ScriptManager control for ajax functionality. When I run my code I am getting following error
Control 'ctl02_Accordion1_AccordionExtender' of type
'AccordionExtender' must be placed inside a form tag with runat=server.
I already used form with runat="server" tag on my consumer page why this problem is coming. To solve this problem I moved my consumer page's form tag to user control this solves my problem but by doing this I can't take advantage of postback on my consumer page. If I put form tag with runat="server" in both user control and consumer page it show error that you can use only one form tag on page. How to solve this problem.
Thanks in advance..
Add a PlaceHolder control onto a form and instead of this.Controls.Add(mycontrol); use PlaceHolder1.Controls.Add(mycontrol);
Or you need to add controls to form's Controls collection. In assumption that form has aspnetForm id you should write: aspnetForm.Controls.Add(mycontrol);
The reason is that Page class has own Controls property thus this.Controls.Add(mycontrol); line add control to Page.Controls collection. But all controls those submit any data to server must be placed in form element otherwise theirs values shouldn't be accessible on server side. This follows from html forms mature: HTML Forms and Input

Is it possible to reference same ascx user control within the same ascx control

Is it possible to use/reference same ascx user control within the same ascx control?
Primarily we want a popup within a popup within a popup - n level based on a condition. The popup is the user control.
I guess this is possible when loading/adding the control programmatically, e.g:
this.Controls.Add(LoadControl("~/mycontrol.ascx"));
But if you do this unconditionally, then you'll get an endless loop.
You can not : Circular file references are not allowed.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.WebUserControl1" %>
<%# Register TagPrefix="test" TagName="test" Src="~/WebUserControl1.ascx"%>
This code is not possible

ASP.NET Controls are not coming in Code-behind IntelliSense

I am having an aspx page where I have added one asp.net text box control with ID and RUNAT attribute. But in Code-behind I am not seeing this control's name in the intellisense.
My page directive in aspx is as follows
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MyProject_UI._Default" %>
I am using VS 2008. Any idea how to get rid of this?
Try using CodeFile instead of CodeBehind. The latter is a hold-over from .NET 1.1.
Also, make sure the namespaces match up between the markup and the code. Do a test compile to be sure.
I have seen this on occasion when I edit a page. When it happens to me, I close the files and open them again and it seems to fix itself.
This will happen if you are trying to include your control in LayoutTemplate. For example if you are using an asp label in a login control you have converted to a LayoutTemplate.
<asp:Login ID="userLogin" runat="server">
<LayoutTemplate>
<!--Username and password controls-->
<asp:Button ID="btnLogin" CommandName="Login" runat="server" Text="Login" />
<asp:Label ID="lblAlert" runat="server"></asp:Label>
</LayoutTemplate>
So your lblAlert will not show up on the code behind take it out of the layouttemplate or use a loop to find the control within the layout object.
var mylabel = (Label)userLogin.FindControl("lblAlert");

Resources