How to maintain state in (asp.net) custom server control?

I am trying to make a custom server control which inherits from DropDownList. I give the control an XML input containing some key/value pairs and my control shows them as a DropDownList. I make the list items in the override Render method like this:

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);
}

The problem is that, when the user selects and item in the list, and the page posts back, the selected item is lost, and the list is re-initialized with the default data.

Does anyone have any idea how to keep the selected item, ie maintain the state?

Here is the complete source:

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 }

Thanks in advance.


You've got two options: ViewState or ControlState.

The difference being ViewState can be overriden by setting EnableViewState="false" in the page directive, whilst ControlState cannot.

Essentially you need to hook into the state bag when you're getting/setting the values of the dropdown.

There's a decent example here where a custom control is derived from the Button class and maintains state between page requests - should fit your scenario nicely.

Hopefully that gets you started.

链接地址: http://www.djcxy.com/p/56660.html

上一篇: WebMethod:关闭XML

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