ASP.Net自定义服务器控件和子控件失去状态

时间:2013-04-22 15:29:53

标签: asp.net servercontrols

我已经构建了一个自定义服务器控件。基本上,这个自定义控件提供了一个文本框和一个浏览器按钮,可以帮助用户填充文本框。在幕后,我有一个复杂的数据结构,描述了上下文和用户选择(下面的简化版本):

    [Serializable]
    public class PickerValue
    {
        public PickerType Type { get; set; }
        public string TargetUrl { get; set; }
        public static PickerValue Default()
        {
            return new PickerValue
            {
                TargetUrl = "/",
                Type = PickerType.Value1
            };
        }
    }

然后,在我的控制中,我声明了这种类型的属性,保持在视图状态:

    public PickerValue Value
    {
        get
        {
            var obj = ViewState["Value"];
            return (PickerValue)(obj != null ? obj : ViewState["Value"] = PickerValue.Default());
        }
        set
        {
            ViewState["Value"] = value;
        }
    }

因为我的自定义控件保持这样的值并且应该引发回发事件,所以我在我的控件中实现了IPostBackDataHandler来转换并读取此值的JSON表示(使用newtonsoft.json)(这将由javascript使用代码):

    public event EventHandler ValueChanged;

    protected virtual void OnValueChanged(EventArgs e)
    {
        if (ValueChanged != null) ValueChanged(this, e);
    }
    public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
    {
        var presentValue = JsonConvert.SerializeObject(Value);
        var postedValue = postCollection[postDataKey];



        if (!string.IsNullOrEmpty(presentValue) && !presentValue.Equals(postedValue))
        {
            Value = JsonConvert.DeserializeObject<PickerValue>(postedValue);
            return true;
        }
        else
        {
            return false;
        }
    }

    public void RaisePostDataChangedEvent()
    {
        OnValueChanged(EventArgs.Empty);
    }

我还自定义控件的渲染,以生成与我的控件值相关的正确<input type='hidden'>

    protected override void RenderContents(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden");
        writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_data");
        writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
        writer.AddAttribute(HtmlTextWriterAttribute.Value, JsonConvert.SerializeObject(Value));
        writer.RenderBeginTag(HtmlTextWriterTag.Input);
        writer.RenderEndTag();
        RenderChildren(writer);
    }

最后,我使用(我猜)使用CreateChildControls的正确方法生成文本框和浏览按钮:

    protected TextBox txtTargetUrl;
    protected Button btnBrowse;
    protected override void CreateChildControls()
    {
        this.txtTargetUrl = new TextBox();
        this.Controls.Add(this.txtTargetUrl);

        this.btnBrowse = new Button
        {
            Text = BrowseButtonText
        };
        this.Controls.Add(this.btnBrowse);
    }

这几乎正常。我的内部输入值由代码正确填充,回发正确地重建了内部值,但我的文本框失去了它的值。每次回发后,文本框仍为空。

我有什么要在代码中纠正以维护子控件的状态?

0 个答案:

没有答案