自定义控件子控件未持久保存到ASP.NET 4.0中的ViewState

时间:2011-05-19 10:49:16

标签: .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="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-tags和一个连接到文本框的标签。

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

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

即。外包装中的所有内容都消失了,文本框中输入的任何内容都无法从后面的代码中检索出来。

下面是FormLabel类的代码。

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

有人可以告诉我们如何让ViewState像以前一样在3.5中运行,在所有控件上 - 包装器和包装控件?

由于

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
}

0 个答案:

没有答案
相关问题