2010-09-24 6 views
3

Je suis à la recherche d'un moyen de charger dynamiquement une page maître afin d'obtenir une collection de ContentPlaceHolders à l'intérieur.Trouver ContentPlaceHolders dans la page principale

Je préférerais ne pas avoir à charger un objet page pour assigner la page maître avant que je puisse accéder à ses contrôles, mais si c'est la seule façon dont je serai heureux de l'utiliser. C'est la façon dont j'espérais qu'il travaillerait:

 Page page = new Page(); 
     page.MasterPageFile = "~/home.master"; 
     foreach (Control control in page.Master.Controls) 
     { 
      if (control.GetType() == typeof(ContentPlaceHolder)) 
      { 
       // add placeholder id to collection 
      } 
     } 

Mais page.Master Déclenche une exception référence nulle. Il semble seulement charger à un moment où une page réelle a été créée dans le cycle de vie de la page.

J'ai même pensé à changer dynamiquement le MasterPageFile de la page en cours sur Page_Init(), en lisant tous les ContentPlaceHolders puis en assignant le MasterPageFile original, mais ce serait horrible!

Y at-il un moyen de charger une page maître en mémoire indépendamment d'une page réelle afin que je puisse accéder aux propriétés de celle-ci? Mon dernier recours impliquera probablement l'analyse du contenu de la page maître pour ContentPlaceHolders, ce qui n'est pas aussi élégant mais pourrait être un peu plus rapide.

Toute personne pouvant vous aider s'il vous plaît? Merci beaucoup.

Répondre

1

Vous devriez pouvoir utiliser LoadControl pour charger la page maître et énumérer la collection Controls.

var site1Master = LoadControl("Site1.Master"); 

Pour trouver les contrôles de contenu dont vous aurez besoin pour effectuer une recherche récursive dans la collection Controls. Voici un exemple rapide et sale.

static class WebHelper 
{ 
    public static IList<T> FindControlsByType<T>(Control root) 
    where T : Control 
    { 
    List<T> controls = new List<T>(); 
    FindControlsByType<T>(root, controls); 
    return controls; 
    } 

    private static void FindControlsByType<T>(Control root, IList<T> controls) 
    where T : Control 
    { 
    foreach (Control control in root.Controls) 
    { 
     if (control is T) 
     { 
     controls.Add(control as T); 
     } 
     if (control.Controls.Count > 0) 
     { 
     FindControlsByType<T>(control, controls); 
     } 
    } 
    } 
} 

ci-dessus peut être utilisé comme suit

// Load the Master Page 
    var site1Master = LoadControl("Site1.Master"); 

    // Find the list of ContentPlaceHolder controls 
    var controls = WebHelper.FindControlsByType<ContentPlaceHolder>(site1Master); 

    // Do something with each control that was found 
    foreach (var control in controls) 
    { 
    Response.Write(control.ClientID); 
    Response.Write("<br />"); 
    } 
+0

Excellent, c'est exactement ce que je voulais faire et d'une façon beaucoup plus élégante. Merci! –

+0

@GarryM, j'ai eu du temps et j'ai nettoyé un peu le code. –

Questions connexes