如何在(asp.net)自定义服务器控件中维护状态?

Posted

技术标签:

【中文标题】如何在(asp.net)自定义服务器控件中维护状态?【英文标题】:How to maintain state in (asp.net) custom server control? 【发布时间】:2010-08-10 08:51:20 【问题描述】:

我正在尝试制作一个继承自 DropDownList 的自定义服务器控件。我给控件一个包含一些键/值对的 XML 输入,我的控件将它们显示为 DropDownList。 我在覆盖 Render 方法中创建列表项,如下所示:

foreach (XElement child in root.Elements("Choice"))

    string title = child.Element("Title").Value;
    string score = child.Element("Score").Value;
    item = new ListItem();
    item.Text = title;
    item.Value = score;

    this.Items.Add(item);

问题是,当用户在列表中选择和项目时,页面回发,所选项目丢失,列表重新初始化为默认数据。

有谁知道如何保留选定的项目,即保持状态?

这里是完整的源代码:

public class MultipleChoiceQuestionView2 : DropDownList

    public MultipleChoiceQuestionView2() : base()
    
    

    protected override void Render(htmlTextWriter writer)
    
        writer.RenderBeginTag(HtmlTextWriterTag.Table);
        writer.RenderBeginTag(HtmlTextWriterTag.Tr);
        writer.RenderBeginTag(HtmlTextWriterTag.Td);
#region Parse Contets
        if (!String.IsNullOrEmpty(this.Contents))
        
            XElement root = XElement.Parse(this.Contents);
            if (root.HasAttributes)
            
                this.NoOfChoices = Int32.Parse(root.Attribute("ItemCount").Value);
            

            this.Items.Clear();
            this.Style.Add("width", "100px");
            this.Style.Add("font-family", "Tahoma");
            this.Items.Clear();
            ListItem item = new ListItem();
            item.Text = "";
            item.Value = "0";
            this.Items.Add(item);
            foreach (XElement child in root.Elements("Choice"))
            
                string title = child.Element("Title").Value;
                string score = child.Element("Score").Value;
                item = new ListItem();
                item.Text = title;
                item.Value = score;
                this.Items.Add(item);
            
        

#endregion
        base.Render(writer);
        writer.RenderEndTag();
        if (this.Required)
        
            RequiredFieldValidator rfv = new RequiredFieldValidator();
            rfv.ControlToValidate = this.ID;
            rfv.InitialValue = "0";
            rfv.Text = "*";
            if (!String.IsNullOrEmpty(this.ValidationGroup))
            
                rfv.ValidationGroup = this.ValidationGroup;
            

            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            rfv.RenderControl(writer);
            writer.RenderEndTag();
        

        writer.RenderEndTag();
        writer.RenderEndTag();
    

#region Properties
    public string Contents
    
        get
        
            return ViewState["Contents"] == null ? "" : ViewState["Contents"].ToString();
        

        set
        
            ViewState["Contents"] = value;
        
    

    private int mNoOfChoices;
    public int NoOfChoices
    
        get
        
            return mNoOfChoices;
        

        set
        
            mNoOfChoices = value;
        
    

    private string mValidationGroup;
    public string ValidationGroup
    
        get
        
            return mValidationGroup;
        

        set
        
            mValidationGroup = value;
        
    

    public string SelectedChoice
    
        get
        
            return "";
        
    

    private bool mRequired = false;
    public bool Required
    
        get
        
            return mRequired;
        

        set
        
            mRequired = value;
        
    
#endregion

提前致谢。

【问题讨论】:

这是一个很好的答案,您可以检查 [ASP.NET Control items collection doesn't work with IList T][1] [1]: ***.com/questions/31947655/… 【参考方案1】:

您有两个选择:ViewState 或 ControlState。

可以通过在页面指令中设置 EnableViewState="false" 来覆盖 ViewState 的区别,而 ControlState 则不能。

当您获取/设置下拉菜单的值时,基本上您需要连接到 状态包

有一个不错的示例 here,其中自定义控件派生自 Button 类并维护页面请求之间的状态 - 应该很好地适合您的场景。

希望这能让你开始。

【讨论】:

以上是关于如何在(asp.net)自定义服务器控件中维护状态?的主要内容,如果未能解决你的问题,请参考以下文章

c# asp.net,添加自定义控件

ASP.NET用户自定义控件

ASP.NET 页生命周期概述

ASP.NET 页生命周期概述1

ASP.NET 自定义控件 - 未知的服务器标记

WebResource-asp.net自定义控件引用外部资源方法