This exact issue has been already discussed before with woritem [16321](https://ajaxcontroltoolkit.codeplex.com/workitem/16321). I was not able to find any other recent discussion about it.
I invite to read that report because symptoms are very well explained by the author.
I updated toolkit version from 30930 (Sep 2009) to 7.1213 (Dec 2013) on a project containing a complex implementation of TabContainer. Before the update I had no issue at all with that page and TabContainer in general, but as soon as I referenced new toolkit version I found out some strange behaviors.
I reduced it all in a very simple, standalone page, attached to this post.
Basically what happens is that when you set one or more tab to be invisible (no matter whether you do it by the attribute on tag declaration or in the code-behind), TabContainer starts to display mixed-content tabs after ActiveTabChanged event, when index requested is equals or greater than the one of the not visible.
Page attached shows it very clearly.
Note: none of the workarounds proposed in the old workitem is working in my environment.
Target framework 3.5, Toolkit version 7.1213, IIS 7.5, Windows 7 64 bit
Comments: If you, like me, cannot easily upgrade to the latest version of Ajax control toolkit, here's an alternative server side only solution. The solution consists of encapsulating the tabcontainer in a new class that works around the different behaviour of ActiveTabIndex between server side and client side . Create a new file in App_Code folder with the following code: The code will basically change the ActiveTabIndex after loading ClientState taking into account the hidden tabs that only reside on the server side. And then when rendering the tabcontainer control, decrease again ActiveTabIndex with the hidden tabs left of the Active Tab. ``` Option Strict On Imports Microsoft.VisualBasic Imports AjaxControlToolkit Namespace myWebControls Public Class AjaxTkTabContainer Inherits AjaxControlToolkit.TabContainer Private Sub AjaxTkTabContainer_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init ' strictly not needed, but give the tabs a nice index. Default all tabindexes are 0, but all is working. For i As Integer = 0 To Me.Tabs.Count - 1 Me.Tabs(i).TabIndex = CShort(i) Next End Sub Protected Overrides Sub LoadClientState(ByVal clientState As String) MyBase.LoadClientState(clientState) ' increase activeTabIndex with number of invisible tabs Dim i As Integer = 0 Dim theActiveTabIndex As Integer = Me.ActiveTabIndex Do If Not Me.Tabs(i).Visible Then theActiveTabIndex += 1 End If i += 1 Loop Until i = theActiveTabIndex OrElse i = Me.Tabs.Count If i < Me.Tabs.Count Then Me.ActiveTabIndex = i End Sub Private Sub AjaxTabContainer_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender ' in case the current tab is not visible, show the first tab rotating to the left that is visible Dim theIterations As Integer = 0 Do Until Me.Tabs(Me.ActiveTabIndex).Visible OrElse theIterations >= Me.Tabs.Count Me.ActiveTabIndex = (Me.ActiveTabIndex - 1) Mod Me.Tabs.Count theIterations += 1 Loop End Sub Protected Overrides Sub RenderChildren(ByVal inWriter As System.Web.UI.HtmlTextWriter) MyBase.RenderChildren(inWriter) ' decrease ActiveTabIndex with invisible tabs before active tab ' count invisibile tabs before active tab ' do this after rendering childern ' in the html result the active tab will have no style attribute (making it visible by default) ' the other tabs are invisible by style style="display:none;visibility:hidden;" ' After the children are rendered, a line of script is rendered that sets the activeTabIndex. ' Since Client side the invisible tabs are not rendered, the activeTabIndex needs to be adjusted (lowered) taking into ' account the invisible tabs ' Sys.Application.add_init(function() { ' $create(AjaxControlToolkit.TabContainer, {"activeTabIndex":1,"clientStateField":$get("cTabContainer_ClientState")}, null, null, $get("cTabContainer")); '}); Dim theCount As Integer = 0 For i As Integer = 0 To Me.ActiveTabIndex - 1 If Not Me.Tabs(i).Visible Then theCount += 1 End If Next Me.ActiveTabIndex -= theCount End Sub End Class ``` in your .aspx or .ascx add reference ``` <%@ Register TagPrefix="my" Namespace="myWebControls" %> ``` Then change the tabcontainer to use the encapsulating control. No other changes are needed use my:AjaxTkTabContainer in stead of AjaxTk:TabContainer. ``` <my:AjaxTkTabContainer id="cTabContainer" runat="server" activetabindex="0" Debug="true" > <ajaxTk:TabPanel ID="cTabPanel1" runat="server" HeaderText="Panel1" > <ContentTemplate> Panel 1 content </ContentTemplate> </ajaxTk:TabPanel> <ajaxTk:TabPanel ID="cTabPanel2" runat="server" HeaderText="Panel2" > <ContentTemplate> panel 2 content </ContentTemplate> </ajaxTk:TabPanel> </my:AjaxTkTabContainer> ```
I invite to read that report because symptoms are very well explained by the author.
I updated toolkit version from 30930 (Sep 2009) to 7.1213 (Dec 2013) on a project containing a complex implementation of TabContainer. Before the update I had no issue at all with that page and TabContainer in general, but as soon as I referenced new toolkit version I found out some strange behaviors.
I reduced it all in a very simple, standalone page, attached to this post.
Basically what happens is that when you set one or more tab to be invisible (no matter whether you do it by the attribute on tag declaration or in the code-behind), TabContainer starts to display mixed-content tabs after ActiveTabChanged event, when index requested is equals or greater than the one of the not visible.
Page attached shows it very clearly.
Note: none of the workarounds proposed in the old workitem is working in my environment.
Target framework 3.5, Toolkit version 7.1213, IIS 7.5, Windows 7 64 bit
Comments: If you, like me, cannot easily upgrade to the latest version of Ajax control toolkit, here's an alternative server side only solution. The solution consists of encapsulating the tabcontainer in a new class that works around the different behaviour of ActiveTabIndex between server side and client side . Create a new file in App_Code folder with the following code: The code will basically change the ActiveTabIndex after loading ClientState taking into account the hidden tabs that only reside on the server side. And then when rendering the tabcontainer control, decrease again ActiveTabIndex with the hidden tabs left of the Active Tab. ``` Option Strict On Imports Microsoft.VisualBasic Imports AjaxControlToolkit Namespace myWebControls Public Class AjaxTkTabContainer Inherits AjaxControlToolkit.TabContainer Private Sub AjaxTkTabContainer_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init ' strictly not needed, but give the tabs a nice index. Default all tabindexes are 0, but all is working. For i As Integer = 0 To Me.Tabs.Count - 1 Me.Tabs(i).TabIndex = CShort(i) Next End Sub Protected Overrides Sub LoadClientState(ByVal clientState As String) MyBase.LoadClientState(clientState) ' increase activeTabIndex with number of invisible tabs Dim i As Integer = 0 Dim theActiveTabIndex As Integer = Me.ActiveTabIndex Do If Not Me.Tabs(i).Visible Then theActiveTabIndex += 1 End If i += 1 Loop Until i = theActiveTabIndex OrElse i = Me.Tabs.Count If i < Me.Tabs.Count Then Me.ActiveTabIndex = i End Sub Private Sub AjaxTabContainer_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender ' in case the current tab is not visible, show the first tab rotating to the left that is visible Dim theIterations As Integer = 0 Do Until Me.Tabs(Me.ActiveTabIndex).Visible OrElse theIterations >= Me.Tabs.Count Me.ActiveTabIndex = (Me.ActiveTabIndex - 1) Mod Me.Tabs.Count theIterations += 1 Loop End Sub Protected Overrides Sub RenderChildren(ByVal inWriter As System.Web.UI.HtmlTextWriter) MyBase.RenderChildren(inWriter) ' decrease ActiveTabIndex with invisible tabs before active tab ' count invisibile tabs before active tab ' do this after rendering childern ' in the html result the active tab will have no style attribute (making it visible by default) ' the other tabs are invisible by style style="display:none;visibility:hidden;" ' After the children are rendered, a line of script is rendered that sets the activeTabIndex. ' Since Client side the invisible tabs are not rendered, the activeTabIndex needs to be adjusted (lowered) taking into ' account the invisible tabs ' Sys.Application.add_init(function() { ' $create(AjaxControlToolkit.TabContainer, {"activeTabIndex":1,"clientStateField":$get("cTabContainer_ClientState")}, null, null, $get("cTabContainer")); '}); Dim theCount As Integer = 0 For i As Integer = 0 To Me.ActiveTabIndex - 1 If Not Me.Tabs(i).Visible Then theCount += 1 End If Next Me.ActiveTabIndex -= theCount End Sub End Class ``` in your .aspx or .ascx add reference ``` <%@ Register TagPrefix="my" Namespace="myWebControls" %> ``` Then change the tabcontainer to use the encapsulating control. No other changes are needed use my:AjaxTkTabContainer in stead of AjaxTk:TabContainer. ``` <my:AjaxTkTabContainer id="cTabContainer" runat="server" activetabindex="0" Debug="true" > <ajaxTk:TabPanel ID="cTabPanel1" runat="server" HeaderText="Panel1" > <ContentTemplate> Panel 1 content </ContentTemplate> </ajaxTk:TabPanel> <ajaxTk:TabPanel ID="cTabPanel2" runat="server" HeaderText="Panel2" > <ContentTemplate> panel 2 content </ContentTemplate> </ajaxTk:TabPanel> </my:AjaxTkTabContainer> ```