.net 4.0 自定义控件子控件未在ASP.NET 4.0中持久化到ViewState

.net 4.0 自定义控件子控件未在ASP.NET 4.0中持久化到ViewState,.net-4.0,controls,viewstate,persist,.net 4.0,Controls,Viewstate,Persist,我们刚刚将ASP.NET web应用程序中的目标框架从3.5切换到4.0。我们遇到了以下问题: 我们有两个自定义控件,它们在3.5中运行良好,但在4.0中,它们没有持久化到ViewState中,其中一个基本上是继承Label类的其他控件的包装器,aspx代码如下所示: <fsc:FormLabel ID="l_purchaserNo" runat="server" CssClass="label" Text="Purchaser"> <asp:TextBox ID="t

我们刚刚将ASP.NET web应用程序中的目标框架从3.5切换到4.0。我们遇到了以下问题:

我们有两个自定义控件,它们在3.5中运行良好,但在4.0中,它们没有持久化到ViewState中,其中一个基本上是继承Label类的其他控件的包装器,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标记和一个连接到文本框的标签

回发后,4.0中的html代码为:

<span id="l_purchaserNo" class="label"></span>

i、 外部包装中的所有内容都消失了,文本框中输入的任何内容都无法从代码隐藏中检索

下面是FormLabel类的代码

我们发现,通过在自定义控件fsc:FormLabel上设置ViewStateMode=Disabled,在asp:TextBox上设置ViewStateMode=Enabled,内部控件将持久化为ViewState,但同时我们在包装器上丢失了ViewState,因为我们转换了包装器标签上的文本,因此我们也需要ViewState(实际上,我们尝试了各种组合,并在fsc:FormLabel上设置ViewStateMode=Enabled没有帮助,无论我们如何在页面上设置ViewStateMode)。EnableViewState在所有级别上都是真的

有人能告诉我们如何让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
}
使用系统;
使用System.Collections.Generic;
使用System.Web.UI;
使用System.Web.UI.WebControl;
名称空间FormLabel
{
公共类FormLabel:标签
{
私生子
{
得到
{
返回控件。计数>0;
}
}
公共重写字符串文本
{
得到
{
如果(!有孩子)
{
返回base.Text;
}
var text=ViewState[ID+“text”]作为字符串;
如果(文本!=null)
{
((LiteralControl)控件[0])。Text=Text;
}
返回((LiteralControl)控件[0]).Text;
}
设置
{
如果(!有孩子)
{
base.Text=值;
返回;
}
((LiteralControl)控件[0])。文本=值;
}
}
公共void SetText(字符串文本)
{
((LiteralControl)控件[0])。Text=Text;
ViewState[ID+“Text”]=文本;
}
需要公共布尔指示器
{
得到
{
objectstate=ViewState[String.Format(“{0}\u-IR”,ID)];
返回状态!=null&(bool)状态;
}
设置
{
ViewState[String.Format(“{0}\u-IR”,ID)]=值;
}
}
受保护的覆盖无效加载(事件参数e)
{           
ViewState[ID+“Text”]=文本;
基础荷载(e);
}
受保护的覆盖无效渲染(HtmlTextWriter编写器)
{
如果(有孩子)
{
列表控件=控件。GetControls();
List validators=Controls.GetValidators();
WriteLabelControl(writer);
所需的writer指示符(writer);
WriteControlHeader(writer、验证器、this.GetFirstControl());
WriteInnerControl(写入程序、控件);
WriteLabelEndControl(writer);
返回;
}
base.Render(writer);
}
私有void WriteLabelControl(HtmlTextWriter编写器)
{
writer.WriteBeginTag(“span”);
WriteAttribute(“id”,ClientID);
WriteAttribute(“类”,CssClass);
foreach(Attributes.Keys中的字符串attributeKey)
{
WriteAttribute(attributeKey,attribute[attributeKey]);
}
writer.Write(htmltextwitter.TagRightChar);
}
专用无效写入程序requiredIndicator(HtmlTextWriter写入程序)
{
如果(需要指示灯)
{
writer.WriteBeginTag(“span”);
WriteAttribute(“类”、“所需指标”);
writer.Write(htmltextwitter.TagRightChar);
writer.WriteEndTag(“span”);
}
}
私有void WriteControlHeader(HtmlTextWriter编写器、IEnumerable验证器、控件用户控件)
{
writer.WriteBeginTag(“标签”);
WriteAttribute(“类”、“头”);
if(userControl!=null)
{
WriteAttribute(“for”,userControl.ClientID);
}
writer.Write(htmltextwitter.TagRightChar);
作者:写(文本);
foreach(验证器中的BaseValidator验证器)
{
validator.CssClass=“错误”;
validator.RenderControl(编写器);
}
writer.WriteEndTag(“标签”);
}
专用静态void writeInnerControl(HtmlTextWriter编写器、IList控件)
{
writer.WriteBeginTag(“span”);
WriteAttribute(“类”、“值容器”);
writer.Write(htmltextwitter.TagRightChar);
for(int i=1;i