Reputation: 23094
I need to write a user control that can be used with the following syntax:
<quiz:Question runat="server">
<Answer>Foo</Answer>
<Answer>Bar</Answer>
</quiz:Question>
I tried the following property declaration:
[ParseChildren(true, "Answer")]
public class Question : UserControl
{
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public string[] Answer { get; set; }
}
But then the Visual Studio editor insist that <Answers >
should be self-closing and I get this exception if I decide otherwise:
Literal content ('Foo') is not allowed within a 'System.String[]'.
I have been looking at <asp:DropDownList>
in Reflector, which inherits from ListControl
which declares the Items
property as follows:
ParseChildren(true, "Items")
public abstract class ListControl
{
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual ListItemCollection Items { get; }
}
It's not really the same as what I want, because in DropDownList
you must add <asp:ListItem>
as children. And there are some things I don't understand about control design, which is currently preventing me from finding the solution:
<asp:ListItem>
tag require a runat="server"
attribute?Upvotes: 11
Views: 1214
Reputation: 1436
I mixed behavior of controls those can have child items (like ListControl), with controls like Panel (ParseChildren=false) :
[ParseChildren(true, "Answers")]
public class Question : WebControl, INamingContainer
{
private AnswerCollection answers;
public virtual AnswerCollection Answers
{
get
{
if (this.answers == null)
{
this.answers = new AnswerCollection();
}
return this.answers;
}
}
public override void RenderControl(HtmlTextWriter writer)
{
//access to each answer value
foreach (var a in this.Answers)
writer.WriteLine(((LiteralControl)a.Controls[0]).Text + "<br/>");
}
}
[ParseChildren(false), PersistChildren(true)]
public class Answer : Control
{
}
public class AnswerCollection : List<Answer>
{
}
Then you would be able to have something like :
<cc1:Question runat="server">
<cc1:Answer>Answer1</cc1:Answer>
<cc1:Answer>Answer2</cc1:Answer>
</cc1:Question>
Hope it helps
Upvotes: 3