views:

1100

answers:

2

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.

A: 

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
}
Ruslan
The controls are placed in markup and based on some business-logic, they are instantiated in the template. The view-state is not loaded, because on every postback, the template is re-instantiated again with new set of control values and previous view-state is lost.
I can't tell w/o looking at the code. I've edited my reply to illustrate theoretical situation. I don't know if it is similar to yours.
Ruslan
A: 

Hi Ruslan,

Your theoretical code is almost near to my situation with only one major difference that I don't extend my template class from IBindable as such rather I provide the controls for the templates in the mark-up itself which is the requirement.

Scott also, makes it clear that if we add the controls to template like you have done

>         #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

then the view-state will automatically be persisted on every postback. All I need is to allow my templates be instantiated in the mark-up and still persist viewstate on postback and allow me to fetch the status of control even if I used to re-initiate the template with some different data.