Click here to Skip to main content
15,884,176 members

ViewState not persisted on custom control in ASP.NET 4.0

EnkelIk asked:

Open original thread
Hi all,

We just switched target framework in our ASP.NET web application from 3.5 to 4.0. We ran into the following problem:

We have a couple of custom controls that worked fine in 3.5 but now with 4.0 they are not persisted in ViewState, one of them is basically a wrapper for other controls that inherits the Label class and the aspx-code looks like this:
<fsc:FormLabel ID="l_purchaserNo" runat="server" CssClass="label" Text="Purchaser">
    <asp:TextBox ID="tb_purchaserNo" runat="server" CssClass="textBox" MaxLength="50" />
</fsc:FormLabel>
and the resulting html is:
<span id="l_purchaserNo" class="label">
    <label class="header" for="tb_purchaserNo">Purchaser</label>
    <span class="valueContainer">
        <input name="tb_purchaserNo" type="text" id="tb_purchaserNo" class="textBox" />
    </span>
</span>
So the control basically just adds a few span-tags and a label that is connected to the textbox.
After postback the html-code in 4.0 was:
<span id="l_purchaserNo" class="label"></span>

i.e. Everything within the outer wrapper was gone and anything entered in the textbox could not be retreived from code behind.
Below you find the code for our FormLabel class.
We found that by setting ViewStateMode=Disabled on our custom control fsc:FormLabel and ViewStateMode=Enabled on the asp:TextBox the inner controls where persisted to ViewState but at the same time we lost ViewState on the wrapper and since we translate the text on the wrapper label we need viewstate for this as well (actually we tried every combination and setting ViewStateMode=Enabled on fsc:FormLabel did not help, regardless of how we set the ViewStateMode on the page). EnableViewState is true on all levels.
Could someone tell us how to get ViewState to work as before in 3.5, on ALL controls - wrapper as well as wrapped controls?
Thanks
Christian, Zeljko, Jonas

using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace FormLabel
{
	public class FormLabel : Label
	{
		private bool HasChildren
		{
			get
			{
				return Controls.Count > 0;
			}
		}
		public override string Text
		{
			get
			{
				if (!HasChildren)
				{
					return base.Text;
				}
				var text = ViewState[ID + "Text"] as String;
				if (text != null)
				{
					((LiteralControl)Controls[0]).Text = text;
				}
				return ((LiteralControl)Controls[0]).Text;
			}
			set
			{
				if (!HasChildren)
				{
					base.Text = value;
					return;
				}
				((LiteralControl)Controls[0]).Text = value;
			}
		}
		public void SetText(string text)
		{
			((LiteralControl)Controls[0]).Text = text;
			ViewState[ID + "Text"] = text;
		}

		public bool IndicateRequired
		{
			get
			{
				object state = ViewState[String.Format("{0}_IR", ID)];
				return state != null && (bool)state;
			}
			set
			{
				ViewState[String.Format("{0}_IR", ID)] = value;
			}
		}
		protected override void OnLoad(EventArgs e)
		{			
			ViewState[ID + "Text"] = Text;
			base.OnLoad(e);
		}
		protected override void Render(HtmlTextWriter writer)
		{
			if (HasChildren)
			{
				List<Control> controls = Controls.GetControls();
				List<BaseValidator> validators = Controls.GetValidators();
				WriteLabelControl(writer);
				WriteRequiredIndicator(writer);
				WriteControlHeader(writer, validators, this.GetFirstControl());
				WriteInnerControls(writer, controls);
				WriteLabelEndControl(writer);
				return;
			}
			base.Render(writer);
		}
		private void WriteLabelControl(HtmlTextWriter writer)
		{
			writer.WriteBeginTag("span");
			writer.WriteAttribute("id", ClientID);
			writer.WriteAttribute("class", CssClass);
			foreach (string attributeKey in Attributes.Keys)
			{
				writer.WriteAttribute(attributeKey, Attributes[attributeKey]);
			}
			writer.Write(HtmlTextWriter.TagRightChar);
		}
		private void WriteRequiredIndicator(HtmlTextWriter writer)
		{
			if (IndicateRequired)
			{
				writer.WriteBeginTag("span");
				writer.WriteAttribute("class", "requiredIndicator");
				writer.Write(HtmlTextWriter.TagRightChar);
				writer.WriteEndTag("span");
			}
		}
		private void WriteControlHeader(HtmlTextWriter writer, IEnumerable<BaseValidator> validators, Control userControl)
		{
			writer.WriteBeginTag("label");
			writer.WriteAttribute("class", "header");
			if (userControl != null)
			{
				writer.WriteAttribute("for", userControl.ClientID);
			}
			writer.Write(HtmlTextWriter.TagRightChar);
			writer.Write(Text);
			foreach (BaseValidator validator in validators)
			{
				validator.CssClass = "Error";
				validator.RenderControl(writer);
			}
			writer.WriteEndTag("label");
		}
		private static void WriteInnerControls(HtmlTextWriter writer, IList<Control> controls)
		{
			writer.WriteBeginTag("span");
			writer.WriteAttribute("class", "valueContainer");
			writer.Write(HtmlTextWriter.TagRightChar);
			for (int i = 1; i < controls.Count; i++)
			{
				controls[i].RenderControl(writer);
			}
			writer.WriteEndTag("span");
		}
		private static void WriteLabelEndControl(HtmlTextWriter writer)
		{
			writer.WriteEndTag("span");
		}
	}
	#region Nested type: Extensions
	public static class Extensions
	{
		public static List<BaseValidator> GetValidators(this ControlCollection controls)
		{
			var validators = new List<BaseValidator>();
			foreach (Control c in controls)
			{
				if (c is BaseValidator)
				{
					validators.Add(c as BaseValidator);
				}
				
			}
			return validators;
		}
		public static List<Control> GetControls(this ControlCollection controls)
		{
			var listcontrols = new List<Control>();
			foreach (Control c in controls)
			{
				if (!(c is BaseValidator))
				{
					listcontrols.Add(c as Control);
				}
			}
			return listcontrols;
		}
		public static Control GetFirstControl(this Control container)
		{
			return (new InputControlFinder().FindFirstInputControl(container));
		}
		private class InputControlFinder
		{
			public Control FindFirstInputControl(Control control)
			{
				Control input = null;
				foreach (Control child in control.Controls)
				{
					if (child is TextBox || child is DropDownList || child is CheckBox)
					{
						input = child;
					}
					else
					{
						input = FindFirstInputControl(child);
					}
					if (input != null)
					{
						return input;
					}
				}
				return input;
			}
		}
	}
	#endregion
}
Tags: ASP.NET, Custom controls, ViewState

Plain Text
ASM
ASP
ASP.NET
BASIC
BAT
C#
C++
COBOL
CoffeeScript
CSS
Dart
dbase
F#
FORTRAN
HTML
Java
Javascript
Kotlin
Lua
MIDL
MSIL
ObjectiveC
Pascal
PERL
PHP
PowerShell
Python
Razor
Ruby
Scala
Shell
SLN
SQL
Swift
T4
Terminal
TypeScript
VB
VBScript
XML
YAML

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the http://www.codeproject.com/info/cpol10.aspx.



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900