2012-01-19 16 views
11

muszę napisać kontrolę użytkownika, który może być używany z następującą składnią:Jak zdefiniować właściwość na formancie użytkownika lub serwera ASP.NET, aby umożliwić wielu wartościom łańcuchów jako zagnieżdżone znaczniki o niestandardowej nazwie znacznika?

<quiz:Question runat="server"> 
    <Answer>Foo</Answer> 
    <Answer>Bar</Answer> 
</quiz:Question> 

Próbowałem następujące oświadczenie nieruchomości:

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

Ale wtedy edytor Visual Studio twierdzą, że <Answers > powinny być samozamykanie się i otrzymuję ten wyjątek, jeśli zdecyduję inaczej:

Dosłowne treści ("Foo") nie są dozwolone w "System.String []".

czekałem na <asp:DropDownList> odbłyśnikiem, która dziedziczy z ListControl który deklaruje właściwość Items następująco:

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

To naprawdę nie jest takie samo jak to, co chcę, bo w DropDownList należy dodać <asp:ListItem> jako dzieci. I istnieje kilka rzeczy, których nie rozumiem o kontroli projektu, który obecnie pozwala mi znalezienie rozwiązania:

  • Dlaczego nie tag <asp:ListItem> wymaga atrybut runat="server"?
  • Czy mogę zadeklarować taką "kontrolę"?
  • Co jest takiego specjalnego w ListItemCollection, że przekłada się na tę szczególną składnię?
  • Jaki kod mogę napisać, który zostanie przetłumaczony na składnię podaną w pierwszym przykładzie kodu powyżej?
+0

czy trzeba używać UserControl lub można rozważyć użycie formantów niestandardowych (kontrole inhertied z WebControl)? – sos00

+0

Zdecydowanie wolałbym kontrolę użytkownika, ponieważ znacznie łatwiej jest generować marżę za pomocą kontroli użytkownika. Czy ma to znaczenie pod względem realizacji? Powinien to być po prostu konstruktor parsera/kontrolera, prawda? –

Odpowiedz

2

mam mieszane zachowanie kontroli te mogą mieć elementów podrzędnych (jak ListControl), przy kontroli jak 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> 
    { 
    } 

Wtedy będzie można mieć coś takiego:

<cc1:Question runat="server"> 
    <cc1:Answer>Answer1</cc1:Answer> 
    <cc1:Answer>Answer2</cc1:Answer> 
</cc1:Question> 

Nadzieja pomaga