如何在ASP.NET用户或服务器控件上定义属性以允许多个字符串值作为具有自定义标记名称的嵌套标记?

Mic*_*out 12 asp.net syntax user-controls properties

我需要编写一个可以使用以下语法的用户控件:

<quiz:Question runat="server">
  <Answer>Foo</Answer>
  <Answer>Bar</Answer>
</quiz:Question>
Run Code Online (Sandbox Code Playgroud)

我尝试了以下属性声明:

[ParseChildren(true, "Answer")]
public class Question : UserControl
{
  [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
  public string[] Answer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是后来Visual Studio编辑坚持<Answers >应该自我关闭,如果我另有决定,我会得到这个例外:

'System.String []'中不允许使用文字内容('Foo').

我一直在寻找<asp:DropDownList>Reflector,它继承自的ListControl声明Items属性如下:

ParseChildren(true, "Items")
public abstract class ListControl
{
  [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
  public virtual ListItemCollection Items { get; }
}
Run Code Online (Sandbox Code Playgroud)

它与我想要的并不完全相同,因为DropDownList你必须添加<asp:ListItem>为孩子.还有一些我对控制设计不了解的事情,目前阻止我找到解决方案:

  • 为什么<asp:ListItem>标签不需要runat="server"属性?
  • 我可以宣布这样一个'控制'吗?
  • 它转换为这种特定语法的ListItemCollection有什么特别之处?
  • 我可以编写哪些代码将转换为上面第一个代码示例中给出的语法?

Ali*_*uri 3

我将可以具有子项(如 ListControl)的控件的行为与诸如 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>
    {
    }
Run Code Online (Sandbox Code Playgroud)

然后你就可以得到类似的东西:

<cc1:Question runat="server">
    <cc1:Answer>Answer1</cc1:Answer>
    <cc1:Answer>Answer2</cc1:Answer>
</cc1:Question>
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你