Showing posts with label adding. Show all posts
Showing posts with label adding. Show all posts

Saturday, March 24, 2012

Exception: Extender controls may not be registered after PreRender

Hello,

I'm dynamically adding UserControls and Extenders for those Controls to my website.
After a postback I get this exception:

"Extender controls may not be registered after PreRender."

What is the (general) problem with that?

Thanks a lot!
Heinz

I am getting the same error message trying to add a UserControl with a SliderExtender on it. This seems like it should be a common problem. I can′t find any general answers for this one, did you find a solution for it Billy_Joe?
This sounds like an issue with ASP.NET AJAX rather than something specific to the Toolkit. Have you searched the ASP.NET AJAX forums?

Hi

Im also getting the "Extender controls may not be registered before PreRender." error and was wondering if anyone found any answers. Im trying to combine a textbox and CalendarExtender together and then use it in another server control. Ive tried to use this control straight on to a page as well and it still fails. The page contains a ScriptManager and an Update panel. Im using the 1.0.10201.0 of the AjaxToolKit. Any response is appriciated.

This is my code so far:

public class CustomDateControl : Control, INamingContainer
{
private TextBox dateTextBox = new TextBox();
private CalendarExtender ajaxCalenderExtender = new CalendarExtender();

public CustomDateControl()
{
}

public string Value
{
get
{
this.EnsureChildControls();
return this.dateTextBox.Text;
}
set
{
this.EnsureChildControls();
this.dateTextBox.Text = value;
}
}

protected override void OnInit(EventArgs e)
{
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
if (scriptManager != null)
{
scriptManager.RegisterExtenderControl<CalendarExtender>(ajaxCalenderExtender, dateTextBox);
}
base.OnInit(e);
}


protected override void CreateChildControls()
{
this.dateTextBox.ID = "dateTextBox";
this.Controls.Add(dateTextBox);
this.ajaxCalenderExtender.ID = "calendarExtender";
this.ajaxCalenderExtender.TargetControlID = dateTextBox.ID;
this.ajaxCalenderExtender.Page = this.Page;
this.Controls.Add(ajaxCalenderExtender);
base.CreateChildControls();
}
}


Hi, did anyone here ever come up with an answer for this? I'm pretty stumped. I'm dynamically adding a ModelPopupExtender to my page; on the first load of the page it works fine, but on any postback it is throwing this error.

Thanks.


This problem has to do with the lifecycle of the webpart (server control) with respect to extender controls such as the ajaxcontrol toolkit.

I've once called MS support on this and was told that AJAX ControlToolkit is not supported , only AJAX.NET Extensions which means the updatepanel and scriptmanager.

It should work, i stuck a scriptmanager on a masterpage of an asp.net web site and the server control (webpart ) worked. I even used the ajax.net extensions tabcontainer and tabcontrols. Once the scriptmanager is on the page before the webpart it should work


Here's what I did to get around it:

At first, I was saving the dynamically added custom controls to a Session variable, pulling them back out as the page reloaded in order to rebuild the Control Tree. (Actually, I was saving the controls in a List<> collection, then saving that list in the session... running a foreach to pull them back out in the page_load event. To add to the complication, the custom controls was really a panel with several labels, text boxes, and AJAX extenders built into it.)

Well, a bit of research shows that controls, even custom controls, can not be re-used directly. It looks like the AJAX extenders are complaining that they had already been pre-rendered because theywere pre-rendered the last time they were put on the page, so obviously they can't be pre-rendered again. (This was a big DUH moment for me.)

So, instead of putting the controls back on the page, I wrote a quick and dirty function... It takes the old custom control as an argument and returns a brand new custom control with the same values...

private CustomPanel RefreshPanel(CustomerPanel oldPanel)
{
CustomPanel newPanel =new CustomPanel();
newPanel.value1 = oldPanel.value1;
// etc...
return newPanel;
}

// and in the Page_Load...

foreach (CustomPanel oldPanelin Session["SavedPanelsList"])
{
updatePanel.ContentTemplateContainer.Controls.Add(RefreshPanel(oldPanel));
}

Yes, it is dirty... It works for now, though, and with a deadline looming, I'm just glad that there will be time to refactor later.

I hope this helps someone get unstuck.

And, of course, the best solution remains to pre-define the controls into the form first, and set them to be visible = false by default. If you're working with 0 to 20+ of these controls, though, it might be best to do things the hard way and mess with the dynamic controls.

Exception while adding ToolkitScriptManager dynamically in OnPreInit event

Hi,

I am trying to add ToolkitScriptManager dynamically as suggested in threadhttp://forums.asp.net/p/1039254/1777798.aspx in OnPreInit event. But I am getting exception "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)." What could be reason?

Here is code...protectedoverridevoid OnPreInit(EventArgs e)

{

if (ToolkitScriptManager.GetCurrent(this.Page) ==null)

{

ToolkitScriptManager Manager =newToolkitScriptManager();

Manager.EnablePartialRendering =true;foreach (Control cinthis.Controls)

{

if (cis System.Web.UI.HtmlControls.HtmlForm)

c.Controls.AddAt(0, Manager);

}

}

}

Here is exception

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

Description:An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details:System.Web.HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

Source Error:

Line 519: if (c is System.Web.UI.HtmlControls.HtmlForm)Line 520:Line 521: c.Controls.AddAt(0, Manager);Line 522: }Line 523: }

Any idea what could resolve this issue?

Thanks, V

Hivishant.patel,

Thanks for your post!

As far as I know, This error happens when asp.net encounterscodeblocks like <%= %>,in a UserControl andthecode-behindthe UserControl is trying to modifythecontrolscollection ofthe page (usually a LoadControl statement).

Nice solutions:

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

TheControlscollectioncannotbemodifiedbecausethecontrolcontainscodeblocks

Solution detail snippet:

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

Now I feel like a complete *** to never have run into this before. That's one hell of an assumption to miss about ASP.NET it seems. I have tons of pages where there's <%= %> markup on it. Especially in script code to get the appropariate ClientID:

<%= this.txtCompany.ClientID %>

Luckily there's a workaround for code like this by using DataBinding expressions instead:

<%# this.txtCompany.ClientID %>

This works fine for simple expressions. The difference here is that <%= %> expressions are embedded into the ASP.NET output as part of the generated Parse Tree class, whereas the <%# %> expressions are embedded at runtime.

Another workaround is to force any script code into the content of a server control and remove it from the Page class or the Content container that you're adding controls to.

<div runat="server">

<script type="text/javascript">

function ShowCreditCard()

{

var IsPayPal = false;

for(x=0; x<4; x++ )

{

var ctl = $("<%= this.txtCCType.ClientID %>_" + x.toString());

if (ctl == null)

break;

if (ctl.value == "PP" && ctl.checked)

{

IsPayPal = true;

break;

}

}

var loCC = $("<%= this.trCreditCard.ClientID %>");

if (loCC == null)

return;

var loCC2 = $("<%= this.trCreditCardExpiration.ClientID %>");

if (IsPayPal)

{

loCC.style.display = "none";

loCC2.style.display = "none";

}

else

{

loCC.style.display = "";

loCC2.style.display = "";

}

}

</script>

</div>

This works as well, although this is also pretty ugly. In my case this is probably the easier solution though, because most of my markup expressions are doing exactly what's happening above: Embedding ClientScript Ids into JavaScript.

I still don't see why the control collection can't be modified if there are <% %> blocks on the page. Those blocks are just turned into Response.Write() commands, or raw code blocks. I don't see how this affects the Controls collection that would require this sort of error.

In my situation here I was able to get by just switching to <%# %> or wrapping sections with a server tag. Even if that's not an option the above code captures the error and goes on. This means the warning icons don't show up, but the rest of the error handling showing the summary and error control linking etc. all still works.

Can anybody think of another more reliable way to inject markup into the page dynamically from outside of the control rendering? In a previous rev of my databinding tools I had custom controls and I simply took over post rendering which was reliable. But this is not so easily done externally… I can think of possibly hooking up the Render method and calling back into my custom control, but man does that seem ugly.

Related Posts:

The Controls collection cannot be modified because the control...

Error:The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)

The Controls collection cannot be modified because the control contains code blocks ...


Jin-Yu Yin - MSFT:

This error happens when asp.net encounterscodeblocks like <%= %>, or <%# %>

Hi Jin-Yu Jin,

This is not correct, but your "Solution detail snippet" also clear about this.

So

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)

only shown when you try to modify acontrol's control collection, when there is <%= %> in thecontrol's root childs . <%# %> not problem at all.

Example:

<asp:PlaceHolder runat="server" id="WeDynamicallyAddControlForThisInCodeBehind">

<%= DateTime.Now.ToString( ) %> <%-- Won't work! --%>

<%# DateTime.Now.ToString( ) %> <%-- Work! (Need a call to DataBind in code behind to real show something) --%>

<asp:PlaceHolder runat="server" id="SomeChild">

<%= DateTime.Now.ToString( ) %> <%-- Work!!! Because we modify the control collection of WeDynamicallyAddControlForThisInCodeBehind and not SomeChild! --%>

<%# DateTime.Now.ToString( ) %> <%-- Of course work! --%>

</asp:PlaceHolder>

<%-- Dynamic controls go here --%>

</asp:PlaceHolder>

</asp:PlaceHolder>

Codebehind:

WeDinamicallyAddControlForThisInCodeBehind.Controls.Add( ... ); //or similar to trigger the error in some case see above.


Thank you for pointing out my mistake,I've corrected it,thanks again:)


Hi Jin-Yu Yin,

Thanks for you reply.

I have visited the posts you specified before I created this post Smile All of posts you specified discuss about custom code we write for user controls, images etc. with <% %> tags inside its markup/code and we can resolve this error by updating code as specified in these post.

In my case; I am not adding any of my own user controls or images etc. I am receving error when I am trying to addToolkitScriptManager in the control list.

How can I change code for ToolkitScriptManager to resolve this error? What should I do to addToolkitScriptManagerdynamically in my base page?

Thanks, Vishant


Hi

It not means that the issue come up when you add any of user controls or images to the page.

It means that the issue come up when you add any contorl(inludeToolkitScriptManager) dynamically in thecode-behind to a page or a user contorl and there iscodeblocks like <%= %> at where the contorl add to.

For example:

<contorlA>

<%= %>

</contorlA>

When you try to add <contorlB> to <contorlA> and want to change the code to:

<contorlA>

<%= %>

<contorlB>

</contorlB>

</contorlA>

Then the error comes up,because you cann't modifythecontrolscollection ofthe contorlA as there is a <%= %>codeblocks in it.

As I mentioned in my first reply, You can resolve this issue by change the code to:

<contorlA>

<div><%= %></div>

</contorlA>

Then add contorls to contorlA dynamically without the error.

Good luck!


Hi V,

Usuallly there could be two problems when you try to add a scriptmanager/toolkitscriptmanager to a page dinamically:

a) Adding dynamically the scriptmanager to the page is tricky, because it should be donevery early in the page lifecycle (forget page_load immediatelly for this...)

This is a good thread how to do this:

Re: Is it possible to add a ScriptManager to a page dynamically?

b) The <% %> code block error.

If you follow the instruction from a) you need to eliminate all <%= %> below the form tag, except when <%= %> are in a child asp.net control of the form tag.

Ps:

Yin-Yu-Yin suggest to use this for workaround:

<contorlA>

<div><%= %></div>

</contorlA>

but this won't work!!!

You need aserver side asp.net control around your code block, for example:

<contorlA>

<asp:Panel runat="server"><%= %></asp:Panel>

</contorlA>

this should work...


Wednesday, March 21, 2012

Event Handlers for Dynamically Added Controls

Hi all,

I'm dynamically creating controls inside an UpdatePanel by declaring something like "Dim abc As New DropDownList()" and then adding this control to a PlaceHolder inside the UpdatePanel.
Now, these controls are added and they appear on the page as they should, however I am also added an event handler dynamically to each control that I'm adding (using AddHandler, since it's VB). However, the events definitely do not register with the UpdatePanel, even though I have set AutoPostBack and also tried adding the control's event to the Triggers collection of the UpdatePanel. The UpdatePanel simplify refreshes when the control event is fired (in this case SelectedIndexChanged of a DropDownList) but the event handler is not fired at any point. Could someone please point me where I'm going wrong here. Thanks in advance...

Hi,

this behavior is possible due to different reasons. Can you let us know when do you create your controls? Is it in page_init, page_load or somewhere else?

Do you create the smae controls on each postback?

Do you assign IDs to your controls?

-yuriy
http://couldbedone.blogspot.com


events can only be added in page_load, or from a function that is called from page load. so unless in your page_load function you have a call to another function called something like, populateUpdatePanelWithControls(), then you will have to change your code.

Its a pain sometimes, but thats just the way the page lifecycle works. Basically when you do the post back it wants to add your events, but because you are referenceing dynamically created controls that do not technicially exist at page_load, the events cannot be linked to the controls. This is why you must create them at page_load


Thanks to both of you. The problem seems to have been solved by moving the code to Page_Load. It wasn't any trouble at all, fortunately, considering the way I'd structured the page.