Saving State Dynamic UserControls...Help!

Posted by Cognitronic on Stack Overflow See other posts from Stack Overflow or by Cognitronic
Published on 2011-01-12T16:18:30Z Indexed on 2011/01/13 16:53 UTC
Read the original article Hit count: 475

I have page with a LinkButton on it that when clicked, I'd like to add a Usercontrol to the page. I need to be able to add/remove as many controls as the user would like. The Usercontrol consists of three dropdownlists. The first dropdownlist has it's auotpostback property set to true and hooks up the OnSelectedIndexChanged event that when fired will load the remaining two dropdownlists with the appropriate values.

My problem is that no matter where I put the code in the host page, the usercontrol is not being loaded properly. I know I have to recreate the usercontrols on every postback and I've created a method that is being executed in the hosting pages OnPreInit method. I'm still getting the following error: The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.

Here is my code: Thank you!!!!

bool createAgain = false;
    IList<FilterOptionsCollectionView> OptionControls
    {
        get
        {
            if (SessionManager.Current["controls"] != null)
                return (IList<FilterOptionsCollectionView>)SessionManager.Current["controls"];
            else
                SessionManager.Current["controls"] = new List<FilterOptionsCollectionView>();
            return (IList<FilterOptionsCollectionView>)SessionManager.Current["controls"];
        }
        set
        {
            SessionManager.Current["controls"] = value;
        }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        Master.Page.Title = Title;
        LoadViewControls(Master.MainContent, Master.SideBar, Master.ToolBarContainer);
    }

    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);
        System.Web.UI.MasterPage m = Master;
        Control control = GetPostBackControl(this);
        if ((control != null && control.ClientID ==
                        (lbAddAndCondtion.ClientID) || createAgain))
        {
            createAgain = true;
            CreateUserControl(control.ID);
        }
    }

    protected void AddAndConditionClicked(object o, EventArgs e)
    {
        var control = LoadControl("~/Views/FilterOptionsCollectionView.ascx");
        OptionControls.Add((FilterOptionsCollectionView)control);
        control.ID = "options" + OptionControls.Count.ToString();
        phConditions.Controls.Add(control);
    }



    public event EventHandler<Insight.Presenters.PageViewArg> OnLoadData;



    private Control FindControlRecursive(Control root, string id)
    {
        if (root.ID == id)
        {
            return root;
        }
        foreach (Control c in root.Controls)
        {
            Control t = FindControlRecursive(c, id);
            if (t != null)
            {
                return t;
            }
        }
        return null;
    }

    protected Control GetPostBackControl(System.Web.UI.Page page)
    {
        Control control = null;
        string ctrlname = Page.Request.Params["__EVENTTARGET"];
        if (ctrlname != null && ctrlname != String.Empty)
        {
            control = FindControlRecursive(page, ctrlname.Split('$')[2]);
        }
        else
        {
            string ctrlStr = String.Empty;
            Control c = null;
            foreach (string ctl in Page.Request.Form)
            {
                if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
                {
                    ctrlStr = ctl.Substring(0, ctl.Length - 2);
                    c = page.FindControl(ctrlStr);
                }
                else
                {
                    c = page.FindControl(ctl);
                }
                if (c is System.Web.UI.WebControls.CheckBox ||
                c is System.Web.UI.WebControls.CheckBoxList)
                {
                    control = c;
                    break;
                }
            }
        }
        return control;
    }


    protected void CreateUserControl(string controlID)
    {
        try
        {
            if (createAgain && phConditions != null)
            {
                if (OptionControls.Count > 0)
                {
                    phConditions.Controls.Clear();
                    foreach (var c in OptionControls)
                    {
                        phConditions.Controls.Add(c);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

Here is the usercontrol's code:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FilterOptionsCollectionView.ascx.cs" Inherits="Insight.Website.Views.FilterOptionsCollectionView" %>


namespace Insight.Website.Views

{ [ViewStateModeById] public partial class FilterOptionsCollectionView : System.Web.UI.UserControl { protected void Page_Load(object sender, EventArgs e) {

    }

    protected override void OnInit(EventArgs e)
    {
        LoadColumns();
        ddlColumns.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(ColumnsSelectedIndexChanged);
        base.OnInit(e);
    }

    protected void ColumnsSelectedIndexChanged(object o, EventArgs e)
    {
        LoadCriteria();
    }

    public void LoadColumns()
    {
        ddlColumns.DataSource = User.GetItemSearchProperties();
        ddlColumns.DataTextField = "SearchColumn";
        ddlColumns.DataValueField = "CriteriaSearchControlType";
        ddlColumns.DataBind();
        LoadCriteria();
    }

    private void LoadCriteria()
    {
        var controlType = User.GetItemSearchProperties()[ddlColumns.SelectedIndex].CriteriaSearchControlType;

        var ops = User.GetItemSearchProperties()[ddlColumns.SelectedIndex].ValidOperators;
        ddlOperators.DataSource = ops;
        ddlOperators.DataTextField = "key";
        ddlOperators.DataValueField = "value";
        ddlOperators.DataBind();

        switch (controlType)
        {
            case ResourceStrings.ViewFilter_ControlTypes_DDL:
                criteriaDDL.Visible = true;
                criteriaText.Visible = false;

                var crit = User.GetItemSearchProperties()[ddlColumns.SelectedIndex].SearchCriteria;
                ddlCriteria.DataSource = crit;
                ddlCriteria.DataBind();
                break;
            case ResourceStrings.ViewFilter_ControlTypes_Text:
                criteriaDDL.Visible = false;
                criteriaText.Visible = true;
                break;
        }
    }

    public event EventHandler OnColumnChanged;
    public ISearchCriterion FilterOptionsValues { get; set; }
}

}

© Stack Overflow or respective owner

Related posts about ASP.NET

Related posts about architecture