This is a migrated thread and some comments may be shown as answers.

Issues adding Context Menus to tree

1 Answer 182 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Nick
Top achievements
Rank 1
Nick asked on 08 Feb 2008, 12:47 AM
I've run across a strange issue when adding RadTreeViewContextMenus to a tree and I'm trying to determine if it's an issue with the telerik controls or something else. What I'm doing is creating a few context menus on Application_Start (in Global.asax) and adding them to a collection within an instance of a singleton. On Page_Load within my pages I'm retreiving these context menus and adding them to the tree as needed.

  1. The first time the page is built/loaded everything works fine and the context menus are added.
  2. If I refresh the page once, the code that adds the context menus completes without error, however at some point just after Page_Load there is an unhandled exception "Script controls may not be registered after PreRender."
  3. If I try to refresh the page after that TreeView.ContextMenus.Add() throws an exception "The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."

I have a project with a very stripped down example of the problem but it doesn't seem like theres a way for me to attach it here, so let me know if you'd like to see it. The full text of the two exceptions is below:

Exception 1

Script controls may not be registered after PreRender.

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.InvalidOperationException: Script controls may not be registered after PreRender.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: Script controls may not be registered after PreRender.]
   System.Web.UI.ScriptControlManager.RegisterScriptControl(TScriptControl scriptControl) +269
   System.Web.UI.ScriptManager.RegisterScriptControl(TScriptControl scriptControl) +99
   Telerik.Web.UI.RadDataBoundControl.RegisterScriptControl() +60
   Telerik.Web.UI.RadDataBoundControl.OnPreRender(EventArgs e) +57
   System.Web.UI.Control.PreRenderRecursiveInternal() +86
   System.Web.UI.Control.PreRenderRecursiveInternal() +170
   System.Web.UI.Control.PreRenderRecursiveInternal() +170
   System.Web.UI.Control.PreRenderRecursiveInternal() +170
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2041

Exception 2

System.Web.HttpException was unhandled by user code

  Message="The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."

  Source="System.Web"

  ErrorCode=-2147467259

  StackTrace:

       at System.Web.UI.ControlCollection.RemoveAt(Int32 index)

       at System.Web.UI.ControlCollection.Remove(Control value)

       at System.Web.UI.Control.AddedControl(Control control, Int32 index)

       at System.Web.UI.ControlCollection.Add(Control child)

       at System.Web.UI.ControlCollection.AddAt(Int32 index, Control child)

       at Telerik.Web.UI.RadTreeViewContextMenuCollection.OnInsertComplete(Int32 index, Object value)

       at System.Web.UI.StateManagedCollection.InsertInternal(Int32 index, Object o)

       at System.Web.UI.StateManagedCollection.System.Collections.IList.Add(Object value)

       at Telerik.Web.UI.RadTreeViewContextMenuCollection.Add(RadTreeViewContextMenu target)

       at _Default.AttachMenus() in e:\Source Control\<snip>\Default.aspx.cs:line 254

       at _Default.Page_Load(Object sender, EventArgs e) in e:\Source Control\<snip>\Default.aspx.cs:line 81

       at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)

       at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)

       at System.Web.UI.Control.OnLoad(EventArgs e)

       at System.Web.UI.Control.LoadRecursive()

       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

1 Answer, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 08 Feb 2008, 08:01 AM
Hi Nick,

ASP.NET controls should be instantiated per every page request. Storing them in session, application or cache may lead to unpredictable results. For example such  controls will hold reference to old page and script manager objects from previous requests which normally should be garbage collected. As a result the garbage collector won't be able to free that memory. More info can be found in this excellent blog post. It describes a similar scenario with the sole difference the controls are cached in session state rather than application state.

In your specific case the context menus are holding reference to an "old" ScriptManager (from the very first time your page is loaded). When the menus try to register as script controls the ScriptManager throws the exception because its PreRender event took place during that first request.
To solve the problem you need to instantiate the context menus for every page request. You can do that in a
"if(!IsPostback)" block - RadTreeView persists its context menus in viewstate and will recreate them automatically after postback. Of course you can cache the data used to populate your context menus. Another caching technique is to store the XML representing a menu:


string xml = RadContextMenu1.GetXml();
CachingSingleton.Items["RadContextMenu1State" = xml;

To attach a project or file you need to open a formal support ticket from your client.net account.

I hope this helps,
Albert
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
Tags
TreeView
Asked by
Nick
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Share this question
or