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, i.e. 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;
}开发者_如何学C
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.
精彩评论