IE Web Controls Tabstrip and Corrupted ListBox ViewState Bug.

E

Eric D. Wilson

I thought I'd post some info about a bug I've found in the way viewstate is
handled (or not handled for that matter) when you dynamically remove a tab
from the IE Web Control TabStrip control.

I've got a web app that uses the tabstrip to partition various types of data
with each tab corrosponding to a "feature". On each tab are several server
controls including ListBoxes. Part of the business logic is that a user can
select an item in a listbox and then click a button to initiate a post back.
On the server I'd check to see what the select index value was and then
provide a pop-up with details specific to the selected item (the pop-up is
created using the RegisterClientScriptBlock() and a JavaScript function
included in the page definition).

When the page initially loads I check to see what features are
enabled/disabled based on a setting in a database. When a feature is disabled
I remove the tab that corrosponds to the feature from the tabstrip in the
Page_Load() event. This only has to be done when IsPostBack is false as the
viewstate will be maintained properly for the tabstrip itself.

This is where the funny part starts.

If there are ASP.NET ListBox controls on any of the subsequent tabs, their
viewstate will be lost when a preceding tab is removed. I haven't tested
every server control yet, but so far this behavior only appears to effect
ListBox controls.

I haven't taken the time to look through the code for the TabStrip,
MultiPage, or PageView yet as I was able to come up with a work around.

To work around the problem you can simply set the Enabled property of the
disabled tab(s) to false. The tab will still be rendered but you won't be
able to activate it.

I've put together a demo of behavior using the tabstrip example that came
with the IE web controls distribution. It's a little contrived but it shows
the problem.

Here's the source for my doctored "tabstrip.aspx" page.

************************************************************
<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls"
Assembly="Microsoft.Web.UI.WebControls" %>
<%@ Page language="c#" Codebehind="tabstrip.aspx.cs" AutoEventWireup="false"
enableViewState="True" Trace="false" Inherits="IEWebCtrlSamples.tabstrip" %>
<HTML>
<body>
<form runat="server">
<iewc:TabStrip ID="tsTest" runat="server"
TabDefaultStyle="background-color:#000000;font-family:verdana;font-weight:bold;font-size:8pt;color:#ffffff;width:79;height:21;text-align:center"
TabHoverStyle="background-color:#777777"
TabSelectedStyle="background-color:#ffffff;color:#000000"
TargetID="mpTest">
<iewc:Tab ID="tabHome" Text="Home" />
<iewc:Tab ID="tabAboutUs" Text="About us" />
<iewc:Tab ID="tabProducts" Text="Products" />
<iewc:Tab ID="tabSupport" Text="Support" />
<iewc:Tab ID="tabContactUs" Text="Contact us" />
</iewc:TabStrip>
<iewc:MultiPage id="mpTest" runat="server" Height="100%">
<iewc:pageView id="pvHome">
<asp:panel ID="panHome" Runat="server">
<br />
Home
<br />
<asp:ListBox ID="lstHome" Runat="server" Width="300px" Rows="10"
EnableViewState="True"></asp:ListBox>
<br />
<asp:button id="btnHome" runat="server" Text="Post Back"></asp:button>
</asp:panel>
</iewc:pageView>
<iewc:pageView id="pvAboutUs">
<asp:panel ID="panAboutUs" Runat="server">
<br />
About Us
<br />
<asp:ListBox ID="lstAboutUs" Runat="server" Width="300px" Rows="10"
EnableViewState="True"></asp:ListBox>
<br />
<asp:button id="btnAboutUs" runat="server" Text="Post
Back"></asp:button>
</asp:panel>
</iewc:pageView>
<iewc:pageView id="pvProducts">
<asp:panel ID="panProducts" Runat="server">
<br />
Products
<br />
<asp:ListBox ID="lstProducts" Runat="server" Width="300px" Rows="10"
EnableViewState="True"></asp:ListBox>
<br />
<asp:button id="btnProducts" runat="server" Text="Post
Back"></asp:button>
</asp:panel>
</iewc:pageView>
<iewc:pageView id="pvSupport">
<asp:panel ID="panSupport" Runat="server">
<br />
Support
<br />
<asp:ListBox ID="lstSupport" Runat="server" Width="300px" Rows="10"
EnableViewState="True"></asp:ListBox>
<br />
<asp:button id="btnSupport" runat="server" Text="Post
Back"></asp:button>
</asp:panel>
</iewc:pageView>
<iewc:pageView id="pvContactUs">
<asp:panel ID="panContactUs" Runat="server">
<br />
Contact Us
<br />
<asp:ListBox ID="lstContactUs" Runat="server" Width="300px" Rows="10"
EnableViewState="True"></asp:ListBox>
<br />
<asp:button id="btnContactUs" runat="server" Text="Post
Back"></asp:button>
</asp:panel>
</iewc:pageView>
</iewc:MultiPage>
</form>
</body>
</HTML>

************************************************************

Here's the source for the codebehind page that removes a tab.

************************************************************

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace IEWebCtrlSamples
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class tabstrip : System.Web.UI.Page
{
protected Microsoft.Web.UI.WebControls.TabStrip tsTest;
protected Microsoft.Web.UI.WebControls.MultiPage mpTest;

protected Microsoft.Web.UI.WebControls.Tab tabHome;
protected Microsoft.Web.UI.WebControls.PageView pvHome;
protected System.Web.UI.WebControls.Panel panHome;
protected System.Web.UI.WebControls.ListBox lstHome;
protected System.Web.UI.WebControls.Button btnHome;

protected Microsoft.Web.UI.WebControls.Tab tabAboutUs;
protected Microsoft.Web.UI.WebControls.PageView pvAboutUs;
protected System.Web.UI.WebControls.Panel panAboutUs;
protected System.Web.UI.WebControls.ListBox lstAboutUs;
protected System.Web.UI.WebControls.Button btnAboutUs;

protected Microsoft.Web.UI.WebControls.Tab tabProducts;
protected Microsoft.Web.UI.WebControls.PageView pvProducts;
protected System.Web.UI.WebControls.Panel panProducts;
protected System.Web.UI.WebControls.ListBox lstProducts;
protected System.Web.UI.WebControls.Button btnProducts;

protected Microsoft.Web.UI.WebControls.Tab tabSupport;
protected Microsoft.Web.UI.WebControls.PageView pvSupport;
protected System.Web.UI.WebControls.Panel panSupport;
protected System.Web.UI.WebControls.ListBox lstSupport;
protected System.Web.UI.WebControls.Button btnSupport;

protected Microsoft.Web.UI.WebControls.Tab tabContactUs;
protected Microsoft.Web.UI.WebControls.PageView pvContactUs;
protected System.Web.UI.WebControls.Panel panContactUs;
protected System.Web.UI.WebControls.ListBox lstContactUs;
protected System.Web.UI.WebControls.Button btnContactUs;

private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
tsTest.Items.Remove(tabProducts);

lstHome.Items.Add("Home 1");
lstHome.Items.Add("Home 2");

lstAboutUs.Items.Add("About Us 1");
lstAboutUs.Items.Add("About Us 2");

lstProducts.Items.Add("Products 1");
lstProducts.Items.Add("Products 2");

lstSupport.Items.Add("Support 1");
lstSupport.Items.Add("Support 2");

lstContactUs.Items.Add("Contact Us 1");
lstContactUs.Items.Add("Contact Us 2");

}

panProducts.Visible = false;
mpTest.Controls.Remove(pvProducts);

// Put user code to initialize the page here
Debug.WriteLine("Tab strip selected index: " + tsTest.SelectedIndex);
}


#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

this.btnHome.Click += new EventHandler(btnHome_Click);
this.btnAboutUs.Click += new EventHandler(btnAboutUs_Click);
this.btnProducts.Click += new EventHandler(btnProducts_Click);
this.btnSupport.Click += new EventHandler(btnSupport_Click);
this.btnContactUs.Click += new EventHandler(btnContactUs_Click);
}
#endregion

private void btnHome_Click(object sender, EventArgs e)
{
Debug.WriteLine("Home post back button clicked.");
Debug.WriteLine("List selected value: " + lstHome.SelectedValue);
}

private void btnAboutUs_Click(object sender, EventArgs e)
{
Debug.WriteLine("About Us post back button clicked.");
Debug.WriteLine("List selected value: " + lstAboutUs.SelectedValue);
}

private void btnProducts_Click(object sender, EventArgs e)
{
Debug.WriteLine("Products post back button clicked.");
Debug.WriteLine("List selected value: " + lstProducts.SelectedValue);
}

private void btnSupport_Click(object sender, EventArgs e)
{
Debug.WriteLine("Support post back button clicked.");
Debug.WriteLine("List selected value: " + lstSupport.SelectedValue);
}

private void btnContactUs_Click(object sender, EventArgs e)
{
Debug.WriteLine("Contact Us post back button clicked.");
Debug.WriteLine("List selected value: " + lstContactUs.SelectedValue);
}
}
}

************************************************************
 
E

Eric D. Wilson

I guess I should have included a little explanation of the demo.

If you're familiar with the tabstrip.aspx demo that's included with the IE
web controls distribution you probably already know that the page just shows
5 tabs (Home, About Us, Products, Support, and Contact Us).

In my altered demo I've added a listbox to each page and a button that
initiates a post back.

During the Page_Load() event I programmatically remove the 'Products' tab.
Now when you click on an item in either the list box on either the 'Support'
or 'Contact Us' tabs and then click the 'Post Back' button what you should
see in the debug output is a printout of the value of the selected item in
the listbox. However, that won't happen because the view state for the
listbox has been lost. If you check the SelectedIndex property it will show
'-1'.

Eric
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top