2009-04-17 6 views
9

Scénario

J'ai une application utilisant des pages Master asp.net dans lequel je voudrais répéter un contenu en haut et en bas d'une page. Actuellement, j'utiliser quelque chose comme ceci:ContentPlaceHolders: Contenu répété

Maître page
<html> 
    <body> 
    <asp:ContentPlaceHolder ID="Foo" runat="server"> 
    </asp:ContentPlaceHolder> 
    <!-- page content --> 
    <asp:ContentPlaceHolder ID="Bar" runat="server"> 
    </asp:ContentPlaceHolder> 
    </body> 
</html> 
Sommaire Page
<asp:Content ID="Top" ContentPlaceHolderID="Foo" runat="server"> 
    <!-- content --> 
</asp:Content> 
<asp:Content ID="Bottom" ContentPlaceHolderID="Bar" runat="server"> 
    <!-- content repeated --> 
</asp:Content> 

Entretien

Comme vous le savez, en répétant les choses dans le code est généralement pas bon. Cela crée des problèmes de maintenance. Voici ce que je voudrais faire, mais évidemment vais pas travailler en raison de l'attribut id répété:

Maître page
<html> 
    <body> 
    <asp:ContentPlaceHolder ID="Foo" runat="server"> 
    </asp:ContentPlaceHolder> 
    <!-- page content --> 
    <asp:ContentPlaceHolder ID="Foo" runat="server"> 
    </asp:ContentPlaceHolder> 
    </body> 
</html> 
Sommaire Page
<asp:Content ID="Top" ContentPlaceHolderID="Foo" runat="server"> 
    <!-- content (no repetition) --> 
</asp:Content> 

possible?

Existe-t-il un moyen de le faire en utilisant asp.net webforms? La solution ne doit pas nécessairement ressembler au contenu ci-dessus, elle doit simplement fonctionner de la même manière.

Notes de

J'utilise asp.net 3.0 dans Visual Studio 2008

+1

J'ai un problème similaire, mais je veux seulement reproduire les titres (pour diverses raisons) dans le code que je maintiens. – Dave

Répondre

3

Comme d'autres l'ont dit, selon le contenu lui-même, il y a des raccourcis qui peuvent être pris en fonction du type de contenu qui sera là. En supposant toutefois que vous ayez besoin du "contenu" pour fonctionner correctement, je suggère un UserControl pour chaque ContentPage qui contient le contenu lui-même et ensuite vous n'avez besoin que de dupliquer une ligne de code.

Exemple

Maître page

<html> 
    <body> 
     <asp:ContentPlaceHolder ID="Foo" runat="server"> 
     </asp:ContentPlaceHolder> 
     <!-- page content --> 
     <asp:ContentPlaceHolder ID="Bar" runat="server"> 
     </asp:ContentPlaceHolder> 
    </body> 
</html> 

Sommaire Page

<asp:Content ID="Top" ContentPlaceHolderID="Foo" runat="server"> 
    <uc1:Page1Control id="page1Control1" runat="server" /> 
</asp:Content> 
<asp:Content ID="Bottom" ContentPlaceHolderID="Bar" runat="server"> 
    <uc1:Page1Control id="page1Control2" runat="server" /> 
</asp:Content> 
+0

Merci pour la réponse. Cela fonctionnerait, mais j'ai l'impression que cela créerait plus de problèmes de maintenance que de répéter le code car j'aurais besoin d'un contrôle séparé dans un fichier séparé pour chaque page. – brad

+1

Je suis d'accord, le seul autre que je puisse penser pour le moment est de boucler les contrôles et de les ajouter dynamiquement. Cela ne vous causera pas de mal avec les gestionnaires d'événements. –

+0

Je ne pense pas que j'utilise des gestionnaires d'événements dans ces espaces réservés, mais plutôt du code html statique, donc cela peut fonctionner. – brad

1

Vous pouvez créer un contrôle utilisateur commun pour le même et l'ajouter à votre page principale en haut en bas &. Vous pouvez créer une propriété décrivant si le contrôle a été chargé en haut ou en bas.

0

Selon le contenu, vous pouvez le faire dans le code. Si son HTML juste le mettre dans une variable et l'assigner à l'autre. Si vous avez des contrôles, vous pouvez passer en boucle sur la collection de contrôles et créer un contrôle en double et le placer dans l'autre zone. Dans les deux cas, le second emplacement ne serait pas un conteneur de contenu auquel une div devrait être attribuée.

5

Dans le cas où vous voulez juste répéter une chaîne, cela a fonctionné pour moi:

<asp:ContentPlaceHolder ID="TitleContent" runat="server" /> 

C un être référencé comme ailleurs:

<% Dim title As LiteralControl = TitleContent.Controls.Item(0) 
    Response.Write(title.Text) 
%> 

Aucune garantie sur ce être la bonne voie d'action bien :)

+0

Un très bon point Dave, j'ai vraiment joué avec ce genre de chose pour atteindre mes objectifs. – brad

5

Hey, si quelqu'un a encore besoin d'une solution pour ce ici est ce que je l'ai fait: le mettre dans le fichier de code de votre page maître

protected override void RenderChildren(HtmlTextWriter writer) 
{ 
    Control mainPlaceHolder = FindControl("MainContentPlaceHolder"); 
    Control doublePlaceHolder = FindControl("ContentDoublePlaceHolder"); 

    StringBuilder sb = new StringBuilder(); 

    using (StringWriter sw = new StringWriter(sb)) 
    using (HtmlTextWriter tw = new HtmlTextWriter(sw)) 
    { 
     mainPlaceHolder.RenderControl(tw); 
    } 

    LiteralControl lc = new LiteralControl(sb.ToString()); 
    doublePlaceHolder.Controls.Add(lc); 

    base.RenderChildren(writer); 
} 

Je ne suis pas sûr des problèmes de performances ici, mais cela fonctionne certainement.

Questions connexes