Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I define a property on an ASP.NET user or server control to allow multiple string values as nested tags with a custom tag name?

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:

  • Why doesn't the <asp:ListItem> tag require a runat="server" attribute?
  • Can I declare such a 'control'?
  • What's so special about the ListItemCollection that it translates to this particular syntax?
  • What code can I write that will translate to the syntax given in the first code example above?
like image 747
Michiel van Oosterhout Avatar asked Jan 19 '12 13:01

Michiel van Oosterhout


People also ask

Which property is used to set the user control on the form?

User Control properties are used to set the values of a User Control from the parent page.

What is the name of the property of ASP.NET page that you can query to determine that ASP.NET page is being requested not data being submitted to Web server?

IsPostBack is a property of the Asp.Net page that tells whether or not the page is on its initial load or if a user has perform a button on your web page that has caused the page to post back to itself. The value of the Page.

What are Runat properties for?

The runat attribute basically tells ASP.Net that it needs to parse the element, its attributes and it's contents as a server control. Enabling code, on the server, to be executed to configure the response. Without it, any child controls contained within the <head> section will not get parsed.

Which is a list controls of ASP.NET application?

ASP.NET has five list-type controls: BulletedList, ListBox, DropDownList, CheckBoxList, and RadioButtonList. These four controls inherits from the same base class, called ListControl.


1 Answers

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

like image 106
Alireza Sabouri Avatar answered Sep 21 '22 11:09

Alireza Sabouri