Мы только что изменили целевой фреймворк в нашем веб-приложении ASP.NET с 3.5 на 4.0.Мы столкнулись со следующей проблемой:
У нас есть пара пользовательских элементов управления, которые отлично работали в 3.5, но теперь с 4.0 они не сохраняются в ViewState, один из них является в основном оболочкой для других элементов управления, которые наследуют метку.класс и aspx-код выглядит следующим образом:
<fsc:FormLabel ID="l_purchaserNo" runat="server" CssClass="label" Text="Purchaser">
<asp:TextBox ID="tb_purchaserNo" runat="server" CssClass="textBox" MaxLength="50" />
</fsc:FormLabel>
, а полученный HTML-код выглядит следующим образом:
<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>
Таким образом, элемент управления в основном просто добавляет несколько тегов span и метку, котораяподключен к текстовому полю.
После обратной передачи html-код в 4.0 был:
<span id="l_purchaserNo" class="label"></span>
т.е. все во внешней оболочке пропало, и все, что было введено в текстовое поле, не могло быть получено из кодапозади.
Ниже вы найдете код для нашего класса FormLabel.
Мы обнаружили, что установив ViewStateMode = Disabled в нашем настраиваемом элементе управления fsc: FormLabel и ViewStateMode = Enabled в asp: TextBox во внутреннейконтролирует, где сохраняется ViewState, но в то же время мы потеряли ViewState на оболочке и, поскольку мы переводим текст на этикетке оболочки, мы нДля этого также нужно использовать viewstate (на самом деле мы пробовали каждую комбинацию и установка ViewStateMode = Enabled для fsc: FormLabel не помогла, независимо от того, как мы установили ViewStateMode на странице).EnableViewState имеет значение true для всех уровней.
Может кто-нибудь сказать нам, как заставить ViewState работать, как раньше, в 3.5, на ВСЕХ элементах управления - обертке, а также обернутых элементах управления?
Спасибо
Кристиан, Желько, Йонас
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
}