R – How to handle view state of child-controls placed on bindable template in composite custom control

asp.netcustom-server-controls

I've a composite data-bound control which hosts a IBindableTemplate and dynamically loads a mark-up based on some condition into the control. Now, when these child controls are loaded into the composite control and postback is there, I lose viewstate of the child controls. Is there a way, I can save viewstate of the child-controls on the postback?

I also ref. to the Scott's explanation using http://scottonwriting.net/sowblog/posts/2129.aspx; but of no use.

Best Answer

There is not enough information. When do you create controls? When do you add them to the Controls collection? What is condition and does it change on postback?

The viewstate is saved automatically at the end of the page cycle (postback or not) given that controls are added at the right time.

If you are adding controls later on, in some event after all initialization has been done, then it is too late.

Update

Without code it is difficult to guess where the break down occurs. Let's examine a Repeater with custom template which could load controls base on some condition. This sample is working, but it would fail if the template assignment was done on Page_Load. Is this something similar to your situation?

Form:

<div>
    <asp:Repeater ID="repeater" runat="server" />
    <asp:Button ID="submitButton" runat="server" Text="Submit" onclick="submitButton_Click" />
    <asp:Button ID="postButton" runat="server" Text="PostBack" />
</div>

Code:

public partial class _Default : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        repeater.ItemTemplate = new MyTemplate();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        //however, if I was to move repeater.ItemTemplate = new MyTemplate() here
        //it would not reload the view state
        if (!IsPostBack)
        {
            repeater.DataSource = new int[] { 1, 2, 3, 4, 5 };
            repeater.DataBind();
        }
    }

    protected void submitButton_Click(object sender, EventArgs e)
    {
        submitButton.Text = "Do it again";
    }
}

public class MyTemplate : IBindableTemplate, INamingContainer
{
    #region IBindableTemplate Members
    public System.Collections.Specialized.IOrderedDictionary ExtractValues(Control container)
    {
        OrderedDictionary dictionary = new OrderedDictionary();
        return dictionary;
    }
    #endregion

    #region ITemplate Members
    public void InstantiateIn(Control container)
    {
        Label label = new Label();
        label.Text = "Label";
        container.Controls.Add(label);

        TextBox textbox = new TextBox();
        container.Controls.Add(textbox);
    }
    #endregion
}