Дочерние элементы пользовательского элемента управления не сохранены в ViewState в ASP.NET 4.0 - PullRequest
1 голос
/ 19 мая 2011

Мы только что изменили целевой фреймворк в нашем веб-приложении 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...