2009-04-17 13 views
9

Escenario

que tienen una aplicación asp.net utilizando páginas maestras en las que me gustaría repetir algo de contenido en la parte superior e inferior de una página. Actualmente utilizo algo como esto:ContentPlaceHolders repetido Contenido:

página maestra
<html> 
    <body> 
    <asp:ContentPlaceHolder ID="Foo" runat="server"> 
    </asp:ContentPlaceHolder> 
    <!-- page content --> 
    <asp:ContentPlaceHolder ID="Bar" runat="server"> 
    </asp:ContentPlaceHolder> 
    </body> 
</html> 
Contenido
<asp:Content ID="Top" ContentPlaceHolderID="Foo" runat="server"> 
    <!-- content --> 
</asp:Content> 
<asp:Content ID="Bottom" ContentPlaceHolderID="Bar" runat="server"> 
    <!-- content repeated --> 
</asp:Content> 

Mantenimiento

Como saben, repitiendo las cosas en el código es por lo general no es bueno. Crea problemas de mantenimiento. Lo siguiente es lo que me gustaría hacer, pero, obviamente, no funciona debido a la repetida atributo id:

página maestra
<html> 
    <body> 
    <asp:ContentPlaceHolder ID="Foo" runat="server"> 
    </asp:ContentPlaceHolder> 
    <!-- page content --> 
    <asp:ContentPlaceHolder ID="Foo" runat="server"> 
    </asp:ContentPlaceHolder> 
    </body> 
</html> 
Contenido
<asp:Content ID="Top" ContentPlaceHolderID="Foo" runat="server"> 
    <!-- content (no repetition) --> 
</asp:Content> 

Posible?

¿Hay alguna manera de hacerlo utilizando asp.net webforms? La solución no necesariamente tiene que parecerse al contenido anterior, solo tiene que funcionar de la misma manera.

Notas

estoy usando asp.net 3.0 en Visual Studio 2008

+1

Tengo un problema similar, pero solo quiero duplicar los títulos (por diversas razones) en el código que estoy manteniendo. – Dave

Respuesta

3

Como han dicho otros, dependiendo del contenido en sí hay atajos que se pueden tomar dependiendo del tipo de contenido que estará allí.

Asumiendo que usted necesita que el "contenido" sea un código asp.net completamente funcional, entonces sugeriría un UserControl para cada página de contenido que contenga el contenido y solo necesita duplicar una línea de código.

Ejemplo

página maestra

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

Contenido

<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

Gracias por la respuesta. Esto funcionaría, pero creo que crearía más problemas de mantenimiento que repetir el código, ya que necesitaría un control separado en un archivo separado para cada página. – brad

+1

Estoy de acuerdo, la única otra cosa en la que puedo pensar por ahora es recorrer los controles y agregarlos dinámicamente. sin embargo, eso le causará infinitos dolores con los manejadores de eventos. –

+0

No creo que esté usando ningún controlador de eventos en esos marcadores de posición, solo html estático en su mayoría, por lo que podría funcionar. – brad

1

Puede crear un control de usuario común para el mismo y añadirlo a tu página maestra en el & arriba abajo. Puede crear una propiedad que describa si el control se ha cargado en la parte superior o inferior.

0

Según el contenido, puede hacer esto en el código. Si es solo HTML, simplemente colócalo en una variable y asígnalo a la otra. Si tiene controles, puede recorrer la colección de controles y crear un control duplicado y colocarlo en la otra área. En cualquier caso, la segunda ubicación no sería un sitio de contenido que un div debería tener.

5

En el caso en el que sólo desea repetir una cadena, esto funcionó para mí:

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

C un ser referenciados en otros lugares como:

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

Sin garantía de que al ser el curso de acción correcto aunque :)

+0

Un muy buen punto Dave, he jugado con este tipo de cosas para lograr mis objetivos. – brad

5

Oye, si alguien todavía tiene una solución para esto aquí está lo que hice: ponerlo en el archivo de código de su página maestra

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); 
} 

No estoy seguro acerca de los problemas de rendimiento aquí, pero ciertamente funciona.

Cuestiones relacionadas