How To: Make Tab control panels load "on-demand"

Several people have asked about how to make the contents of their tabs load when the user first clicks them, thereby reducing initial page size.

I can think of several ways to do this with varying levels of complexity, but here's away you can do right now with minimal hacking.  We'll think about how to build this in.  But for now...

Basically we can do this with UpdatePanels. 

What we'll do is:

  1. Add an UpdatePanel inside each TabPanel

  2. Add a hidden button to trigger that update panel

  3. Add a Panel with Visible="false" that has the content we want to load inside of it (Visible false prevents it from rendering at all)

  4. Write some JavaScript to trigger that button.

Let's get started.  First, we just create an empty AJAX Enabled project and drop an AjaxControlToolkit TabContainer on the page.  Add some TabPanels:

<act:TabContainer ID="tc1" runat="server" >

<act:TabPanel HeaderText="TabPanel0" runat="server" >


This is the inital tab.



<act:TabPanel HeaderText="TabPanel1" runat="server" >


We want to load this later.




Next, to each TabPanel, add an UpdatePanel, and inside that a Button and a Panel.  Note the OnClick handler on the Button and the naming of the button and the panel.  On the button, set it's style to "display:none;" so the browser hides it.

<act:TabPanel HeaderText="TabPanel1" runat="server">


<asp:UpdatePanel ID="up1" runat="server">


<asp:Button ID="TabButton1" runat="server"  OnClick="TabButton_Click"  style="display:none;"/>

<asp:Panel ID="TabContent1" runat="server" Visible="False">

We want to load this later






Now on the server side, we add some code to handle the click.  Again, note how we use the naming. 

Protected Sub TabButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)

' find the sibling with the name that starts with TabContainer


Dim containerId As String = "TabContent" & tc1.ActiveTabIndex

Dim panel As Panel = tc1.ActiveTab.FindControl(containerId)

If (Not panel Is Nothing) Then

panel.Visible = True

End If

End Sub

Here, we just flip the Visible property to true.  You could, of course, do a databinding operation here or whatever.

Now we just wire it up.  We add some JavaScript to handle this hookup for us to the top of the page, and set the "OnClientActiveTabChanged" property on the TabContainer. 

<act:TabContainer ID="tc1" runat="server" ActiveTabIndex="0" OnClientActiveTabChanged="loadTabPanel" > 

Note this WILL NOT set the content for the initial tab.  For the tab you start with, you really should render that to begin with.  If you need to do this dynamically, you'll need to add some code to fire the activeTabChanged event on the TabContainer when it loads.  The JavaScript is fairly straight forward, but I won't paste it in here.  You can grab it from the project.

<script type="text/ecmascript" src="OnDemandTabs.js"/>

Test it - we're done!  When the active tab changes, the UpdatePanel will fire and we'll go back to the server.  Note how this is set up so you can do it for N tabs - just keep using TabButtonX/TabContentX as the naming pattern and it'll work.


We can even add an UpdateProgress here to make it look nice, though on the local machine we'll probably never see it.

<asp:UpdateProgress id="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">



 Presto.  Hope that helps.  Full project attached.  Works in all browsers.

Comments (16)
  1. I translated (on developer fusion) your function above to C# which gave me:

    protected void TabButton_Click(object sender, System.EventArgs e)


           string containerId = "TabContent" + TabContainer1.ActiveTabIndex;

           Panel panel = TabContainer1.ActiveTab.FindControl(containerId);

           if (((panel != null)))


               panel.Visible = true;



    But I get the following error:

    Cannot implicitly convert type ‘System.Web.UI.Control’ to ‘System.Web.UI.WebControls.Panel’. An explicit conversion exists (are you missing a cast?)

    Any thoughts on this?

  2. Right – you need a cast on that line:

    Panel panel = (Control) TabContainer1…

  3. Dflying Chen says:


  4. Last week the ASP.NET AJAX Control Toolkit team released Build 10618 of the ASP.NET AJAX Control Toolkit

  5. ASP.NET says:

    Last week the ASP.NET AJAX Control Toolkit team released Build 10618 of the ASP.NET AJAX Control Toolkit.

  6. Last week the ASP.NET AJAX Control Toolkit team released Build 10618 of the ASP.NET AJAX Control Toolkit.

  7. ganezh says:

    i tried the code snippet above… but i am not able to see the gridview in one of the panel.

  8. ganezh says:

    well got it working but everytime i click on the tab it does a full postback so i tried inserting the tabcontainer into update panel so that the postback i async but it doesn’t display the content in the tab as it did previously without update panel

  9. nigelhughes says:


    This is a great bit of code and it works well in a c# project I’m developing. However, how do you get the tabs to update the content? I have the tabs populated via a database and the underlying data changes based on a dropdown list (outside of the tabs) so I want to update the data on the tabs when the tabs are clicked on if the data has changed. I can see the; in the .js file but can’t figure out how to wire this up.


  10. 拾荒时代 says:

    浏览器 UpdatedASP.NETAJAXControlToolkitReleaseandNewASP.NETAJAXVideos/Articles …

  11. Jacky_Xu says:


    本期共有4篇文章(目前ASP.NET日渐凋敝阿,这么少东西都不好意思拿出来,以后不如改成两周推荐一次了): 如何根据需要加载某一Tab中的内容


  12. rox19840702 says:

    Updated ASP.NET AJAX Control Toolkit Release and New ASP.NET AJAX Videos/Articles

  13. Rehan Farooq ( says:

    I tried to download the attached zipped file but it seams to be corrupt and I can’t unzip it. Can you please verify that, I have tried to download multiple time but there result was same.

  14. Dennis The Geek says:

    Why not just use the OnActiveTabChanged event?  Test for which tab has been clicked then load your tables accordingly.

  15. umaima says:

    I cant download the zip….seems to be corrupt…Please HELP!!

  16. Arjun says:

    Hi sburke, It is a very good article. This code very helpful for me to implement this lazy loading in my application.

Comments are closed.

Skip to main content