简体   繁体   中英

How to save TabContainer to Viewstate?

I've been struggling with saving a TabContainer to a viewstate variable that would load all of the TabPanels of that TabContainer. (Would page be loaded faster?). Pardon me if the question is not properly formatted; I'm still new to asp.net, here's my code:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        CreateTabbedPanel();
        Response.Write("New Tabs Loaded");
    }
    else
    {
        // Here i would need to load the TabContainer from the viewstate variable
        Response.Write("Tabs Loaded from ViewState");
    }
}

private void CreateTabbedPanel()
{
    TabPanel tp = null;

    string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
    using (SqlConnection con = new SqlConnection(CS))
    {
        SqlCommand cmd = new SqlCommand("select Description from TblProductType", con);
        con.Open();
        SqlDataReader rdr = cmd.ExecuteReader();
        while (rdr.Read())
        {
            tp = new TabPanel();
            tp.HeaderText = rdr["Description"].ToString();                    
            TabContainer1.Tabs.Add(tp);
        }
    }
    // Here i would need to create the viewstate variable
}

And this is my webform:

<form id="form1" runat="server">
    <div>
        <ajaxToolkit:TabContainer ID="TabContainer2" runat="server" 
           ActiveTabIndex="1" AutoPostBack="false">
        </ajaxToolkit:TabContainer>
    </div>
</form>

What do I need to do?

If you wish to save a .Net object to ViewState, you need to make sure that the object supports serialization/deserialization. However, this unlikely increase performance.

ViewState data is rendered into a specific hidden field. If you save complex objects into ViewState, you greatly increase HTML page size. Next, serialization/deserialization also takes time.

And finnaly, you cannot store ASP.NET control in ViewState because of ASP/NET page and control life cycle . When yo create and add a control into a page control hierarchy, it goes through all stages of ASP.NET life cycle: Init, Load, Render, [saving in ViewSate], Unload. When you get the control from the ViewState next time, the control state will be 'after-render'. If you add such control into a new page control hierarchy, the control in 'after-render' state starts going through Init, Load and Render stages again. Although it can operate in the case of primitive controls (Labes, TextBoxes, etc.), it totally breaks control life cycle and causes different strange issues in complex controls.

If you create ASP.NET controls dynamically, I strongly recommend you re-create them on every new page request as ASP.NET page life cycle requires .

Assuming you only need to save few tab names, you can use ViewState . Otherwise I'd recommend Session as it allows to store complex objects at server side without having to post them into the page, it takes less code but you also need to handle session expired.

The collection of tabs is read-only, non serializable, etc. However this code can be used to save headers in CreateTabbedPanel() .

private void SaveTabs()
{
    TabPanel[] tabs = new TabPanel[TabContainer1.Tabs.Count];
    TabContainer1.Tabs.CopyTo(tabs, 0);
    ViewState["tabs"] = tabs.Select(t=>t.HeaderText).ToArray();
}

When page load is not post back:

private void LoadTabs()
{
    string[] headers = (string[])ViewState["tabs"];
    if(headers!=null)
    {
        foreach (string header in headers)
        {
            TabContainer1.Tabs.Add(new TabPanel() { HeaderText = header });
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM