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

InvalidOperationException when loading dynamically RadComboBoxes with ITemplate

3 Answers 64 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Jerome MAILLEY
Top achievements
Rank 1
Jerome MAILLEY asked on 12 Oct 2012, 10:19 AM
Hi,

I have an ASPX page (WebReportGenerator.aspx) which contains an ASCX custom control (Palette.ascx). That custom control is in fact just a panel where I load some RadComboboxes dynamically based upon the results of a stored procs.

WebReportGenerator.aspx :
<body>
    <form id="formWebReportGenerator" runat="server" onmouseup="DisableDrag();" onmousemove="resizePanel();">
    <CustomControl:Palette ID="PaletteControl" runat="server">
    </CustomControl:Palette>
    </form>
</body>

The page_load of the WebReportGenerator just create some RadComboBoxes and ask to the CustomControl Palette to display them in an PlaceHolder.

WebReportGenerator.aspx.cs :
protected void Page_Load(object sender, EventArgs e)
      {
          GetSomeComboBoxes();
          PaletteControl.WebReportGeneratorView = this;
          PaletteControl.SetDimensionsPanel(ContextSelector);//ContextSelector is a class which contain some ComboBoxes
      }


As I said previously my custom control Palette.ascx have a Place Holder which is in an UpdatePanel.

Palette.ascx :
<asp:UpdatePanel runat="server">
    <ContentTemplate>
        <asp:PlaceHolder ID="DimensionsHolder" runat="server"></asp:PlaceHolder>
    </ContentTemplate>
</asp:UpdatePanel>

Here is what my SetDimensionsPanel function looks like :

Palette.ascx.cs:
internal void SetDimensionsPanel(ContextSelector contextSelector)
{
    foreach (var comboBox in contextSelector.HierarchicalComboBoxes.Values)
    {
        DimensionsHolder.Controls.Add(comboBox);
    }
}


The RadComboBoxes are in fact in a Custom User Control (ComboBoxView.ascx). Please look at the code lower.

ComboBoxView.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ComboBoxView.ascx.cs"
    Inherits="AS.Cpm.Web.Site.WebReportGenerator.Views.ComboBoxView" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<script type="text/javascript">
 
    function ClientNodeChecked_<%= ClientID %>(sender, eventArgs) {
        var node = eventArgs.get_node();
        var combo = $find("<%= RadComboBox.ClientID %>");
        var checkedNodes = sender.get_checkedNodes();
        var dimensionString = "";
        for (var i = 0; i < checkedNodes.length; i++) {
                dimensionString += checkedNodes[i].get_text();
            }
        combo.set_text(dimensionString);
        combo.attachDropDown();
    }
 
    function OnClientDropDownOpenedHandler_<%= ClientID %>(sender, eventArgs)
            {
                var tree = sender.get_items().getItem(0).findControl("RadTreeView1");
                var selectedNode = tree.get_selectedNode();
                if (selectedNode)
                {
                    selectedNode.scrollIntoView();
                }
            }
 
    function ClientNodeChecking_<%= ClientID %>(sender, eventArgs) {
        var node = eventArgs.get_node();
        var combo = $find("<%= RadComboBox.ClientID %>");
        var checkedNodes = sender.get_checkedNodes();
        for (var i = 0; i < checkedNodes.length; i++) {
                checkedNodes[i].set_checked(false);
            }
    }
 
    function ClientItemChecking_<%= ClientID %>(sender, eventArgs) {
        var combo = $find("<%= RadComboBox.ClientID %>");
        var node = eventArgs.get_item();
        var checkedItems = sender.get_checkedItems();
        for (var i = 0; i < checkedItems.length; i++) {
                checkedItems[i].set_checked(false);
            }
    }
</script>
<div id="DimensionLabelBgLeft"></div>
<div id="DimensionLabelBg"><asp:Label ID="Label" runat="server" CssClass="labelComboBox"></asp:Label></div>
<div id="DimensionLabelBgRight"></div>
<telerik:RadComboBox ID="RadComboBox" runat="server" HighlightTemplatedItems="True" AutoPostBack="true"
    AllowCustomText="true" ChangeTextOnKeyBoardNavigation="true" MaxHeight="200px"
    Width="100%">
</telerik:RadComboBox>

ComboBoxView.ascx.cs
public partial class ComboBoxView : System.Web.UI.UserControl
{
    protected List<RadTreeNode> radTreeNodes;
    protected List<RadComboBoxItem> radComboBoxItems;
    Boolean multiSelection;
 
 
    protected void Page_Load(object sender, EventArgs e)
    {
    }
 
    /// <summary>
    /// Init hierarchical combobox
    /// </summary>
    /// <param name="entity">The entity</param>
    /// <param name="entityCode">The entity code</param>
    /// <param name="radTreeNodes">The tree nodes</param>
    /// <param name="multiSelection">true if it allows multi selection, else false</param>
    public void InitHierarchicalComboBox(String label, List<RadTreeNode> radTreeNodes, Boolean multiSelection = true)
    {
        this.radTreeNodes = radTreeNodes;
        setLabel(label);
        this.multiSelection = multiSelection;
    }
 
    /// <summary>
    /// Init non hierarchical combobox
    /// </summary>
    /// <param name="entity">The entity</param>
    /// <param name="entityCode">The entity code</param>
    /// <param name="radComboBoxItems">The combobox items</param>
    /// <param name="multiSelection">true if it allows multi selection, false else</param>
    public void InitNonHierarchicalComboBox(String label, List<RadComboBoxItem> radComboBoxItems, Boolean multiSelection = true)
    {
        this.radComboBoxItems = radComboBoxItems;
        setLabel(label);
        this.multiSelection = multiSelection;
    }
 
    /// <summary>
    /// Set the label of the combobox
    /// </summary>
    /// <param name="label">The text label</param>
    private void setLabel(String label)
    {
        Label.Text = label;
    }
 
    protected override void OnInit(EventArgs e)
    {
        var test = this;
        RadComboBox radComboBox = (RadComboBox)FindControl("RadComboBox");
        radComboBox.Items.Clear();
        radComboBox.OnClientDropDownOpened = "OnClientDropDownOpenedHandler_" + this.ClientID;
        if (radComboBox != null)
        {
            if (radTreeNodes != null)
            {                  
                radComboBox.ItemTemplate = new MyTreeView(this, radTreeNodes, multiSelection);
                radComboBox.Items.Add(new RadComboBoxItem(""));
                StringBuilder comboBoxText = new StringBuilder();
                foreach (var checkedNode in (radComboBox.ItemTemplate as MyTreeView).RadTreeView.CheckedNodes)
                    comboBoxText.Append(checkedNode.Text);
                radComboBox.Text = comboBoxText.ToString();
            }
 
        }
        base.OnInit(e);
    }
 
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        //Debug.WriteLine("**WRG diagnostics -> OnPreRender ComboBox : {0}", entity.Code);
        RadComboBox radComboBox = (RadComboBox)FindControl("RadComboBox");
        if (radComboBoxItems != null)
        {
            if (!multiSelection)
                radComboBox.OnClientItemChecking = "ClientItemChecking_" + this.ClientID;
            radComboBox.CheckBoxes = true;
            foreach (var radComboBoxItem in radComboBoxItems)
            {
                radComboBox.Items.Add(radComboBoxItem);
            }
        }
    }
 
 
    /// <summary>
    /// Return the checked item of the combobox
    /// </summary>
    /// <returns></returns>
    public String GetCheckedItemText()
    {
        RadComboBox radComboBox = (RadComboBox)FindControl("RadComboBox");
        if(radComboBox.Text != String.Empty)
            return radComboBox.Text;
        return null;
    }
}
 
/// <summary>
/// The treeview template for the HierarchicalComboBox
/// </summary>
public class MyTreeView : ITemplate
{
    RadTreeView radTreeView;
    public RadTreeView RadTreeView { get { return radTreeView; } }
    List<RadTreeNode> radTreeNodes;
    ComboBoxView hierarchicalComboBox;
    Boolean multiSelection;
 
    public MyTreeView(ComboBoxView hierarchicalComboBox, List<RadTreeNode> radTreeNodes, Boolean multiSelection)
    {
        this.radTreeNodes = radTreeNodes;
        this.hierarchicalComboBox = hierarchicalComboBox;
        this.multiSelection = multiSelection;
    }
 
    public void InstantiateIn(System.Web.UI.Control container)
    {
        radTreeView = new RadTreeView();
        radTreeView.CheckBoxes = true;
        radTreeView.OnClientNodeChecked = "ClientNodeChecked_" + hierarchicalComboBox.ClientID;
        if(!multiSelection)
            radTreeView.OnClientNodeChecking = "ClientNodeChecking_" + hierarchicalComboBox.ClientID;
        radTreeView.Nodes.AddRange(radTreeNodes);
        //radTreeView.NodeCheck += new RadTreeViewEventHandler(RadTreeView_NodeCheck);
        container.Controls.Add(radTreeView);
    }
}

Here is the code to create a ComboBoxView :
//Non hierarchical
ComboBoxView _hierarchicalComboBoxAge = (ComboBoxView)new UserControl().LoadControl("~/Controls/ComboBoxView.ascx");
_hierarchicalComboBoxAge.InitNonHierarchicalComboBox("", CreateSomeItems("Age"), false);
_hierarchicalComboBoxAge.ID = "Age" + "§" + "NotDefined";
comboBoxViews.Add(_hierarchicalComboBoxAge);
 
//Hierarchical
ComboBoxView _hierarchicalComboBoxTree = (ComboBoxView)new UserControl().LoadControl("~/Controls/ComboBoxView.ascx");
_hierarchicalComboBoxTree.InitHierarchicalComboBox("", CreateSomeNodes("Tree"), false);
_hierarchicalComboBoxTree.ID = "Tree" + "§" + "NotDefined";
comboBoxViews.Add(_hierarchicalComboBoxTree);

The problem :

When I first load the page everything is ok. I get my ComboBoxes in my ContextSelector object which is stored in the ViewState of the page and there is no Exception fired. On post back, I have to clear the placeholder and then add some different ComboBoxes. However on each postback I have an Exception :

Request URL
 
[12/10/2012 11:35:54] http://localhost:90/WindowsIntegratedWebSite/WebReportGenerator/Views/WebReportGeneratorView.aspx?ReportId=42
 
Exception Details
 
System.InvalidOperationException: Les contrôles de script ne peuvent pas être inscrits avant PreRender.
 
Source
 
System.Web.Extensions
 
Target Site
 
Void RegisterScriptControl[TScriptControl](TScriptControl)
 
Stack Trace
   Ã  System.Web.UI.ScriptControlManager.RegisterScriptControl[TScriptControl](TScriptControl scriptControl)
   Ã  Telerik.Web.UI.RadDataBoundControl.RegisterScriptControl()
   Ã  Telerik.Web.UI.RadDataBoundControl.ControlPreRender()
   Ã  Telerik.Web.UI.RadTreeView.OnPreRender(EventArgs e)
   Ã  System.Web.UI.Control.PreRenderRecursiveInternal()
   Ã  System.Web.UI.Control.AddedControl(Control control, Int32 index)
   Ã  AS.Cpm.Web.Site.WebReportGenerator.Views.MyTreeView.InstantiateIn(Control container) dans C:\dev\Cpm\CpmNet\WebSite\WebReportGenerator\Views\ComboBoxView.ascx.cs:ligne 157
   Ã  Telerik.Web.UI.ControlItemContainer.ApplyTemplate(ControlItem item)
   Ã  Telerik.Web.UI.ControlItemContainer.InitializeItem(ControlItem item)
   Ã  Telerik.Web.UI.ControlItem.SetItemContainer(ControlItemContainer itemContainer)
   Ã  Telerik.Web.UI.ControlItemCollection.OnInsertComplete(Int32 index, Object value)
   Ã  System.Web.UI.StateManagedCollection.InsertInternal(Int32 index, Object o)
   Ã  System.Web.UI.StateManagedCollection.System.Collections.IList.Add(Object value)
   Ã  System.Web.UI.StateManagedCollection.LoadAllItemsFromViewState(Object savedState)
   Ã  System.Web.UI.Control.LoadViewStateRecursive(Object savedState)
   Ã  System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState)
   Ã  System.Web.UI.Control.LoadViewStateRecursive(Object savedState)
   Ã  System.Web.UI.Control.AddedControl(Control control, Int32 index)
   Ã  AS.Cpm.Web.Site.WebReportGenerator.Views.PaletteUserControl.SetDimensionsPanel(ContextSelector contextSelector) dans C:\dev\Cpm\CpmNet\WebSite\WebReportGenerator\Views\Palette.ascx.cs:ligne 60
   Ã  AS.Cpm.Web.Site.WebReportGeneratorView.Page_Load(Object sender, EventArgs e) dans C:\dev\Cpm\CpmNet\WebSite\WebReportGenerator\Views\WebReportGeneratorView.aspx.cs:ligne 169
   Ã  System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   Ã  PageBase.OnLoad(EventArgs e) dans C:\dev\Cpm\CpmNet\WebSite\Code\PageBase.cs:ligne 180
   Ã  System.Web.UI.Control.LoadRecursive()
   Ã  System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 
Data
 
System.Collections.ListDictionaryInternal

The reason why I'm opening that thread here is because when I replace the ComboBoxes with simple Button, it works perfectly.

So does anyone know how to fix this or has a better solution to this?

Thanks.

Romain.

3 Answers, 1 is accepted

Sort by
0
Ivana
Telerik team
answered on 17 Oct 2012, 08:46 AM
Hi Jerome,

Would you please open a support ticket on the matter and send a sample project so we will be able to test the very same scenario on which you are working?

Thank you!

Kind regards,
Ivana
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Jerome MAILLEY
Top achievements
Rank 1
answered on 17 Oct 2012, 03:44 PM
Hi,

I figured out my issue. I think the problem was because I stored a list of ComboBox in the ViewState of the page as a common object.

public Dictionary<string, ComboBoxView> HierarchicalComboBoxes
{
    get
    {
        return (Dictionary<string, ComboBoxView>)ViewState["HierarchicalComboBoxes"]);
    }
    set
    {
        ViewState["HierarchicalComboBoxes"] = value;
    }
}

On each postback I added them to the placeholder by getting the ViewState field. Now, to fix the problem, I dynamically re-create the comboboxes with control.LoadControl() and then add them in the placeholder. It works as I want without any Exception.

Thank you,
Best Regards,
Romain.
0
Ivana
Telerik team
answered on 19 Oct 2012, 11:38 AM
Hi Jerome,

Thank you for sharing the solution of your scenario. I am sure it will be helpful if someone runs into the same problem.

Regards,
Ivana
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
Tags
ComboBox
Asked by
Jerome MAILLEY
Top achievements
Rank 1
Answers by
Ivana
Telerik team
Jerome MAILLEY
Top achievements
Rank 1
Share this question
or