2008-12-02 7 views
5

Páginas maestras de ASP.NET - cosas esenciales.Quiero un UserControl maestro (una página maestra, pero para UserControls)

Sin embargo, tengo muchos UserControls muy similares en mis proyectos, podría ser un diseño estándar para un AJAX ModalPopup, o algo más complicado.

Ojalá pudiera deshacerme de algunos de mis códigos duplicados (tanto en archivos ascx como en código subyacente) con algunos Master User Controls.

¿Alguien tiene alguna sugerencia de una manera de lograr esto?

Respuesta

2

Lo más cercano que puedo sugerir para lo que estás buscando es un templated custom control. Desafortunadamente, compartir controles entre proyectos es mucho más fácil si se trata de controles personalizados, sin un archivo ascx.

0

Herencia. Usted construye el control base como una clase base, y luego hereda de él.

+2

He hecho esto para el lado del código subyacente (es decir mi archivo UserControl.ascx.cs hereda de mi BaseUserControl en lugar de System.Web.UI.UserControl. Sin embargo, esto me ayuda en términos de agregar controles HTML y de servidor estándar a mi control base. –

0

También puede colocar el control de usuario anidado en un control de posición en un control de usuario "maestro". Usar el método Load que acepta la ruta virtual al archivo ascx para cargar el control apropiado.

1

me las arreglé para conseguir que esto funcione usando el siguiente código:

public class MasterLoader : UserControl 
{ 
    MasterUserControl _masterUserControl; 

    protected override void CreateChildControls() 
    { 
     Controls.Clear(); 
     base.CreateChildControls(); 

     Controls.Add(MasterControl); 
    } 

    protected override void AddedControl(Control control, int index) 
    { 
     if (control is MasterUserControl) 
      base.AddedControl(control, index); 
     else 
      MasterControl.ContentArea.Controls.Add(control); 
    } 

    private MasterUserControl MasterControl 
    { 
     get 
     { 
      if (_masterUserControl== null) 
       _masterUserControl= (MasterUserControl)LoadControl("~/MasterUserControl.ascx"); 

      return _masterUserControl; 
     } 
    } 
} 

controles de usuario para niños heredan de la clase MasterLoader. El control maestro de usuario incluía un control de marcador de posición que expuse como propiedad pública llamada ContentArea.

public partial class MasterUserControl: UserControl 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    public PlaceHolder ContentArea 
    { 
     get 
     { 
      return phContent; 
     } 
    } 
} 

El enlace de eventos y el estado de vista funcionan como se esperaba sin ningún cambio en ninguno de los controles de usuario.

4

esta es una vieja pregunta, pero tengo una solución robusta para cualquiera que tropiece con esto.

en App_Code, crear un archivo y pega este código:

namespace MasterControls 
{ 
    // code written by alexander taylor on 2011-08-22. http://www.alexsapps.com 

    public abstract class ChildUserControl : UserControl 
    { 
     Control master; 

     public abstract string MasterControlVirtualPath { get; } 

     protected override void OnInit(EventArgs e) 
     { 
      master = LoadControl(MasterControlVirtualPath); 
      Controls.Add(master); 

      base.OnInit(e); 
     } 

     protected override void Render(HtmlTextWriter writer) 
     { 
      master.RenderControl(writer); 
     } 
    } 
    public class ControlContentPlaceHolder : Control 
    { 
     protected override void Render(HtmlTextWriter writer) 
     { 
      ControlContent found = null; 

      foreach (Control c in NamingContainer.NamingContainer.Controls) 
      { 
       ControlContent search; 
       search = c as ControlContent; 
       if (search != null && search.ControlContentPlaceHolderID.Equals(ID)) 
       { 
        found = search; 
        break; 
       } 
      } 

      if (found != null) 
      {     
       //write content of the ContentControl 
       found.RenderControl(writer); 
      } 
      else 
      { 
       //use default content 
       base.Render(writer); 
      } 
     } 
    } 
    public class ControlContent : Control 
    { 
     public string ControlContentPlaceHolderID { get; set; } 
    } 

} 

ejemplo "control maestro" (equivalente de página maestra)

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MasterControl1.ascx.cs" Inherits="MasterControl1" %> 
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %> 

<p>content 1 below:<br /> 
<masterControls:ControlContentPlaceHolder ID="myContent1" runat="server"> 
    default content 1 here! 
</masterControls:ControlContentPlaceHolder></p> 

<p>content 2 below:<br /> 
<masterControls:ControlContentPlaceHolder ID="myContent2" runat="server"> 
    default content 2 here! 
</masterControls:ControlContentPlaceHolder></p> 

ejemplo "control secundario" (equivalente de la página)

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ChildControl1.ascx.cs" Inherits="Control1" %> 
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %> 

<masterControls:ControlContent ControlContentPlaceHolderID="myContent1" runat="server"> 
    custom content 1 
</masterControls:ControlContent> 

<masterControls:ControlContent ControlContentPlaceHolderID="myContent2" runat="server"> 
    custom content 2 
</masterControls:ControlContent> 

en el código detrás del control secundario

using MasterControls; 

//you must inherit the ChildUserControl class! 
public partial class Control1 : ChildUserControl 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    public override string MasterControlVirtualPath 
    { 
     //below, type the location to the master control 
     //you wish to apply to this control 
     get { return "~/MasterControl1.ascx"; } 
    } 
} 
Cuestiones relacionadas