2010-11-10 27 views
2

Je travaille sur un menu de navigation.
J'ai créé ci-dessous ServerControl et cela fonctionne, mais je veux permettre aux utilisateurs d'ajouter des contrôles ASP.NET standard dans mes balises ServerControl comme label, image et ainsi de suite.Ajouter des contrôles enfants dans les balises ServerControl?

<MdsMenu:ServerControlMenu ID="ServerControlMenu1" runat="server"> 
    <MdsMenu:animation AnimationSpeed="Normal" AnimationType="Opacity_Height" Delay="1000" DropShadow="true" /> 
    <!-- HERE HAS TO HAVE SOME STANDARD ASP.NET CONTROLS --> 
    <!-- e.g <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> --> 
    </MdsMenu:MenuItem> 
</MdsMenu:ServerControlMenu> 

Mon problème ici est que la façon dont je peux obtenir des contrôles de l'enfant au sein <MdsMenu:MenuItem> et leur montrer comme comme ils sont dans la sortie.

P.S:
Je RenderContents méthode écraser

protected override void RenderContents(HtmlTextWriter output) 
{ 
    output.Write(OutPutStringBuilder.ToString()); 
} 

Répondre

10

Je pense que vous aurez juste à jeter [ParseChildren(false), PersistChildren(true)] sur la classe qui représente la balise <MdsMenu:MenuItem/>. Les contrôles enfants écrits à l'intérieur de la balise doivent alors être disponibles au moment de l'exécution dans la propriété Controls du contrôle.

MISE À JOUR: J'ai lancé un projet de test rapide pour démontrer que cela fonctionne réellement. (Apparemment, les gens aiment downvote sans évaluer réellement si une réponse est correcte.)

Ce contrôle personnalisé a le comportement que vous attendez:

[ParseChildren(false), PersistChildren(true)] 
public partial class SuperDiv : System.Web.UI.UserControl 
{ 
    public override void RenderControl(HtmlTextWriter writer) 
    { 
     writer.Write("<div class=\"super\">"); 
     writer.Write(Controls.Count); 

     foreach (Control i in Controls) 
      i.RenderControl(writer); 

     writer.Write("</div>"); 
    } 
} 

Ainsi, le balisage ASP.NET suivant:

<test:SuperDiv runat="server"> 
    <asp:Label runat="server">Hello, World!</asp:Label> 
</test:SuperDiv> 

entraînera le code HTML suivant étant rendu:

<div class="super">3 
    <span>Hello, World!</span> 
</div> 

(3 parce que les deux nœuds de texte qui contiennent des espaces que sont aussi les enfants du contrôle, ainsi que l'étiquette.)

+0

peut vous fournir peut-être un article à propos de pourquoi ajouter "[ParseChildren (false), PersistChildren (true)]" est la solution, cela semble être une solution obscure. – Letseatlunch

+2

@Letseatlunch - voir la section des remarques de la documentation: http://msdn.microsoft.com/fr-fr/library/system.web.ui.persistchildrenattribute.aspx PersistChildrenAttribute est utilisé en combinaison avec ParseChildrenAttribute pour déterminer comment imbriqué le contenu d'un contrôle est interprété. Si PersistChildrenAttribute est true et ParseChildrenAttribute est false, le contenu imbriqué contenu dans un contrôle serveur ASP.NET est conservé en tant que contrôles. Si PersistChildrenAttribute est false et ParseChildrenAttribute est true, le contenu imbriqué est conservé en tant que propriétés du contrôle serveur. –

+0

cette solution semble fonctionner, sauf si ne gère pas ce genre de choses <% = String.Format ("{0} .blah", "091")%> ou tout simplement texte – Letseatlunch

1

vous devez faire votre acte de contrôle Web comme un conteneur (comme le panneau de contrôle)

il suffit d'ajouter les attributs ci-dessous montrent à votre web classe de contrôle utilisateur

[ParseChildren(false)] 
    [PersistChildren(true)] 
    [Designer(typeof(PanelDesigner))] 
    public class MyOwnControl:WebControl 
    { 




    } 

puis sur la page .aspx vous pourrez faire le ci-dessous:

<cc1:MyOwnControl ID="MyOwnControl1" runat="server"> 
     <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> 
    </cc1:MyOwnControl>