Partager via


Spécification de la page maître par programmation (C#)

par Scott Mitchell

Examine la définition de la page maître de la page de contenu par programmation via le gestionnaire d’événements PreInit.

Introduction

Depuis l’exemple inaugural de création d’une disposition à l’échelle du site à l’aide de pages maîtres, toutes les pages de contenu ont référencé leur page maître de manière déclarative via l’attribut MasterPageFile de la @Page directive. Par exemple, la directive suivante @Page lie la page de contenu à la page Site.mastermaître :

<%@ Page Language="C#" MasterPageFile="~/Site.master" ... %>

La Page classe de l’espace System.Web.UI de noms inclut une MasterPageFile propriété qui retourne le chemin d’accès à la page maître de la page de contenu ; il s’agit de cette propriété définie par la @Page directive. Cette propriété peut également être utilisée pour spécifier par programmation la page maître de la page de contenu. Cette approche est utile si vous souhaitez affecter dynamiquement la page maître en fonction de facteurs externes, tels que l’utilisateur qui visite la page.

Dans ce tutoriel, nous ajoutons une deuxième page maître à notre site web et décider dynamiquement de la page maître à utiliser lors de l’exécution.

Étape 1 : Examiner le cycle de vie de la page

Chaque fois qu’une demande arrive sur le serveur web pour une page de ASP.NET qui est une page de contenu, le moteur ASP.NET doit fusionner les contrôles de contenu de la page dans les contrôles ContentPlaceHolder correspondants de la page maître. Cette fusion crée une hiérarchie de contrôle unique qui peut ensuite passer par le cycle de vie de la page classique.

La figure 1 illustre cette fusion. L’étape 1 de la figure 1 montre les hiérarchies de contrôle de contenu et de contrôle de page maître initiales. À la fin de l’étape PreInit, les contrôles de contenu de la page sont ajoutés aux espaces réservés ContentPlaceHolders correspondants dans la page maître (étape 2). Après cette fusion, la page maître sert de racine de la hiérarchie de contrôle fusionnée. Cette hiérarchie de contrôle fusionnée est ensuite ajoutée à la page pour produire la hiérarchie de contrôle finalisée (étape 3). Le résultat net est que la hiérarchie de contrôle de la page inclut la hiérarchie de contrôle fusionnée.

Les hiérarchies de contrôle de la page maître et de la page de contenu sont fusionnées pendant l’étape de préinit

Figure 01 : Les hiérarchies de contrôle de la page maître et de la page de contenu sont fusionnées pendant l’étape de préinit (cliquez pour afficher l’image de taille complète)

Étape 2 : Définition de laMasterPageFilepropriété à partir du code

La page maître qui participe à cette fusion dépend de la valeur de la propriété de l’objet Page MasterPageFile . La définition de l’attribut MasterPageFile dans la @Page directive a l’effet net de l’affectation de la Pagepropriété 's MasterPageFile pendant l’étape d’initialisation, qui est la première étape du cycle de vie de la page. Nous pouvons également définir cette propriété par programmation. Toutefois, il est impératif que cette propriété soit définie avant la fusion dans la figure 1.

Au début de l’étape PreInit, l’objet Page déclenche son PreInit événement et appelle sa OnPreInit méthode. Pour définir la page maître par programmation, nous pouvons créer un gestionnaire d’événements pour l’événement PreInit ou remplacer la OnPreInit méthode. Examinons ces deux approches.

Commencez par ouvrir Default.aspx.csle fichier de classe code-behind pour la page d’accueil de notre site. Ajoutez un gestionnaire d’événements pour l’événement de PreInit la page en tapant le code suivant :

protected void Page_PreInit(object sender, EventArgs e) 
{ 
}

À partir de là, nous pouvons définir la MasterPageFile propriété. Mettez à jour le code afin qu’il affecte la valeur « ~/Site.master » à la MasterPageFile propriété.

protected void Page_PreInit(object sender, EventArgs e) 
{
    this.MasterPageFile = "~/Site.master"; 
}

Si vous définissez un point d’arrêt et commencez par le débogage, vous verrez que chaque fois que la Default.aspx page est visitée ou chaque fois qu’une publication est effectuée sur cette page, le Page_PreInit gestionnaire d’événements s’exécute et la MasterPageFile propriété est affectée à « ~/Site.master ».

Vous pouvez également remplacer la méthode de OnPreInit la Page classe et définir la MasterPageFile propriété là-bas. Pour cet exemple, ne définissons pas la page maître dans une page particulière, mais plutôt à partir de BasePage. Rappelez-vous que nous avons créé une classe de page de base personnalisée (BasePage) dans la spécification du titre, des balises meta et d’autres en-têtes HTML dans le didacticiel de page maître. Remplace actuellement BasePage la méthode de OnLoadComplete la Page classe, où elle définit la propriété de Title la page en fonction des données de la carte de site. Nous allons également mettre à jour BasePage pour remplacer la OnPreInit méthode pour spécifier par programmation la page maître.

protected override void OnPreInit(EventArgs e) 
{ 
    this.MasterPageFile = "~/Site.master"; 
    base.OnPreInit(e); 
}

Étant donné que toutes nos pages de BasePagecontenu dérivent de , toutes ont désormais leur page maître affectée par programmation. À ce stade, le PreInit gestionnaire d’événements est Default.aspx.cs superflu ; n’hésitez pas à le supprimer.

Qu’en est-il de la@Pagedirective ?

Ce qui peut être un peu déroutant, c’est que les propriétés des pages de MasterPageFile contenu sont désormais spécifiées à deux endroits : par programmation dans la méthode de la BasePage classe et par le biais de OnPreInit l’attribut dans la MasterPageFile directive de chaque page de @Page contenu.

La première étape du cycle de vie de la page est l’étape d’initialisation. Pendant cette phase, la Page propriété de MasterPageFile l’objet reçoit la valeur de l’attribut MasterPageFile dans la @Page directive (si elle est fournie). L’étape PreInit suit l’étape d’initialisation, et c’est ici que nous définissons par programme la Page propriété de MasterPageFile l’objet, remplaçant ainsi la valeur affectée à partir de la @Page directive. Étant donné que nous définissons la propriété de l’objet Page par programmation, nous pourrions supprimer l’attribut MasterPageFile de la @Page directive sans affecter l’expérience de l’utilisateur final.MasterPageFile Pour vous convaincre de cela, passez en avant et supprimez l’attribut MasterPageFile de la @Page directive, Default.aspx puis visitez la page via un navigateur. Comme prévu, la sortie est la même que avant la suppression de l’attribut.

Indique si la MasterPageFile propriété est définie via la @Page directive ou par programmation est inconsequentiale à l’expérience de l’utilisateur final. Toutefois, l’attribut MasterPageFile de la @Page directive est utilisé par Visual Studio au moment du design pour produire la vue WYSIWYG dans le Concepteur. Si vous revenez dans Default.aspx Visual Studio et accédez au Concepteur, vous verrez le message « Erreur de page maître : la page comporte des contrôles qui nécessitent une référence de page maître, mais aucun n’est spécifié » (voir la figure 2).

En bref, vous devez laisser l’attribut MasterPageFile dans la @Page directive pour profiter d’une expérience riche au moment du design dans Visual Studio.

Visual Studio utilise la classe <span=@Page l’attribut MasterPageFile de la directive pour afficher le mode Création » />

Figure 02 : Visual Studio utilise l’attribut de MasterPageFile la @Page directive pour afficher le mode Création (cliquez pour afficher l’image de taille complète)

Étape 3 : Création d’une autre page maître

Étant donné que la page maître d’une page de contenu peut être définie par programmation au moment de l’exécution, il est possible de charger dynamiquement une page maître particulière en fonction de certains critères externes. Cette fonctionnalité peut être utile dans les situations où la disposition du site doit varier en fonction de l’utilisateur. Par exemple, une application web de moteur de blog peut permettre à ses utilisateurs de choisir une disposition pour leur blog, où chaque disposition est associée à une page maître différente. Lors de l’exécution, lorsqu’un visiteur consulte le blog d’un utilisateur, l’application web doit déterminer la disposition du blog et associer dynamiquement la page maître correspondante à la page de contenu.

Examinons comment charger dynamiquement une page maître au moment de l’exécution en fonction de certains critères externes. Notre site web ne contient actuellement qu’une seule page maître (Site.master). Nous avons besoin d’une autre page maître pour illustrer le choix d’une page maître au moment de l’exécution. Cette étape se concentre sur la création et la configuration de la nouvelle page maître. L’étape 4 examine la détermination de la page maître à utiliser au moment de l’exécution.

Créez une page maître dans le dossier racine nommé Alternate.master. Ajoutez également une nouvelle feuille de style au site web nommé AlternateStyles.css.

Ajouter une autre page maître et fichier CSS au site web

Figure 03 : Ajouter une autre page maître et fichier CSS au site web (cliquez pour afficher l’image de taille complète)

J’ai conçu la Alternate.master page maître pour que le titre s’affiche en haut de la page, centré et sur un arrière-plan marine. J’ai distribué la colonne gauche et déplacé ce contenu sous le MainContent contrôle ContentPlaceHolder, qui s’étend désormais sur toute la largeur de la page. En outre, j’ai nixé la liste des leçons non ordonnées et l’ai remplacée par une liste horizontale ci-dessus MainContent. J’ai également mis à jour les polices et les couleurs utilisées par la page maître (et, par extension, ses pages de contenu). La figure 4 montre Default.aspx quand vous utilisez la Alternate.master page maître.

Remarque

ASP.NET inclut la possibilité de définir des thèmes. Un thème est une collection d’images, de fichiers CSS et de paramètres de propriété de contrôle Web liés au style qui peuvent être appliqués à une page au moment de l’exécution. Les thèmes sont le moyen d’aller si les dispositions de votre site diffèrent uniquement dans les images affichées et par leurs règles CSS. Si les dispositions diffèrent plus considérablement, telles que l’utilisation de différents contrôles Web ou l’utilisation d’une disposition radicalement différente, vous devez utiliser des pages maîtres distinctes. Consultez la section Autres lectures à la fin de ce tutoriel pour plus d’informations sur les thèmes.

Nos pages de contenu peuvent désormais utiliser une nouvelle apparence

Figure 04 : Nos pages de contenu peuvent désormais utiliser une nouvelle apparence (cliquez pour afficher l’image de taille complète)

Lorsque le balisage des pages maîtres et de contenu est fusionné, la MasterPage classe vérifie que chaque contrôle de contenu dans la page de contenu fait référence à un ContentPlaceHolder dans la page maître. Une exception est levée si un contrôle de contenu qui fait référence à un ContentPlaceHolder inexistant est trouvé. En d’autres termes, il est impératif que la page maître affectée à la page de contenu dispose d’un ContentPlaceHolder pour chaque contrôle de contenu dans la page de contenu.

La Site.master page maître comprend quatre contrôles ContentPlaceHolder :

  • head
  • MainContent
  • QuickLoginUI
  • LeftColumnContent

Certaines pages de contenu de notre site web incluent seulement un ou deux contrôles de contenu ; d’autres incluent un contrôle de contenu pour chacun des ContentPlaceHolders disponibles. Si notre nouvelle page maître (Alternate.master) peut jamais être affectée à ces pages de contenu qui ont des contrôles de contenu pour tous les ContentPlaceHolders, Site.master il est essentiel d’inclure Alternate.master également les mêmes contrôles ContentPlaceHolder que Site.master.

Pour que votre Alternate.master page maître ressemble à la mienne (voir la figure 4), commencez par définir les styles de la page maître dans la AlternateStyles.css feuille de style. Ajoutez les règles suivantes dans AlternateStyles.css:

body 
{ 
 font-family: Comic Sans MS, Arial; 
 font-size: medium; 
 margin: 0px; 
} 
#topContent 
{ 
 text-align: center; 
 background-color: Navy; 
 color: White; 
 font-size: x-large;
 text-decoration: none; 
 font-weight: bold; 
 padding: 10px; 
 height: 50px;
} 
#topContent a 
{ 
 text-decoration: none; 
 color: White; 
} 
#navContent 
{ 
 font-size: small; 
 text-align: center; 
} 
#footerContent 
{ 
 padding: 10px; 
 font-size: 90%; 
 text-align: center; 
 border-top: solid 1px black; 
} 
#mainContent 
{ 
 text-align: left; 
 padding: 10px; 
}

Ensuite, ajoutez le balisage déclaratif suivant à Alternate.master. Comme vous pouvez le voir, Alternate.master contient quatre contrôles ContentPlaceHolder avec les mêmes ID valeurs que les contrôles ContentPlaceHolder dans Site.master. En outre, il inclut un contrôle ScriptManager, qui est nécessaire pour ces pages de notre site web qui utilisent l’infrastructure ASP.NET AJAX.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head id="Head1" runat="server"> 
 <title>Untitled Page</title>
 <asp:ContentPlaceHolder id="head" runat="server">
 </asp:ContentPlaceHolder> 
 <link href="AlternateStyles.css" rel="stylesheet" type="text/css" /> 
</head> 
<body> 
 <form id="form1" runat="server"> 
 <asp:ScriptManager ID="MyManager" runat="server"> 
 </asp:ScriptManager>
 <div id="topContent">
 <asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx" 
 Text="Master Pages Tutorials" /> 
 </div>
 <div id="navContent">
 <asp:ListView ID="LessonsList" runat="server" 
 DataSourceID="LessonsDataSource">
 <LayoutTemplate>
 <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> 
 </LayoutTemplate>
 <ItemTemplate>
 <asp:HyperLink runat="server" ID="lnkLesson" 
 NavigateUrl='<%# Eval("Url") %>' 
 Text='<%# Eval("Title") %>' /> 
 </ItemTemplate>
 <ItemSeparatorTemplate> | </ItemSeparatorTemplate> 
 </asp:ListView>
 <asp:SiteMapDataSource ID="LessonsDataSource" runat="server" 
 ShowStartingNode="false" /> 
 </div>
 <div id="mainContent">
 <asp:ContentPlaceHolder id="MainContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </div> 
 <div id="footerContent">
 <p> 
 <asp:Label ID="DateDisplay" runat="server"></asp:Label> 
 </p>
 <asp:ContentPlaceHolder ID="QuickLoginUI" runat="server"> 
 </asp:ContentPlaceHolder>
 <asp:ContentPlaceHolder ID="LeftColumnContent" runat="server"> 
 </asp:ContentPlaceHolder>
 </div> 
 </form>
</body> 
</html>

Test de la nouvelle page maître

Pour tester cette nouvelle page maître, mettez à jour la méthode de OnPreInit la BasePage classe afin que la MasterPageFile propriété soit affectée à la valeur « ~/Alternate.master », puis visitez le site web. Chaque page doit fonctionner sans erreur, à l’exception de deux : ~/Admin/AddProduct.aspx et ~/Admin/Products.aspx. L’ajout d’un produit à DetailsView ~/Admin/AddProduct.aspx génère une NullReferenceException ligne de code qui tente de définir la propriété de la GridMessageText page maître. Lors de la visite ~/Admin/Products.aspx d’un InvalidCastException fichier est levée lors du chargement de la page avec le message : « Impossible de convertir l’objet de type « ASP.alternate_master » en type « ASP.site_master ».

Ces erreurs se produisent parce que la Site.master classe code-behind inclut des événements publics, des propriétés et des méthodes qui ne sont pas définies dans Alternate.master. La partie balisage de ces deux pages a une @MasterType directive qui fait référence à la Site.master page maître.

<%@ MasterType VirtualPath="~/Site.master" %>

En outre, le gestionnaire d’événements de ItemInserted DetailsView inclut ~/Admin/AddProduct.aspx du code qui convertit la propriété faiblement typée Page.Master en objet de type Site. La @MasterType directive (utilisée de cette façon) et la conversion dans le ItemInserted gestionnaire d’événements couplent étroitement les pages et ~/Admin/Products.aspx les ~/Admin/AddProduct.aspx pages à la Site.master page maître.

Pour rompre ce couplage serré, nous pouvons avoir Site.master et Alternate.master dériver d’une classe de base commune qui contient des définitions pour les membres publics. Ensuite, nous pouvons mettre à jour la @MasterType directive pour référencer ce type de base commun.

Création d’une classe de page maître de base personnalisée

Ajoutez un nouveau fichier de classe au App_Code dossier nommé BaseMasterPage.cs et faites-le dériver de System.Web.UI.MasterPage. Nous devons définir la méthode et la RefreshRecentProductsGrid GridMessageText propriété dans BaseMasterPage, mais nous ne pouvons pas simplement les déplacer là-bas Site.master , car ces membres fonctionnent avec des contrôles Web spécifiques à la Site.master page maître ( RecentProducts GridView et GridMessage Label).

Ce que nous devons faire est de configurer BaseMasterPage de telle manière que ces membres sont définis là, mais sont réellement implémentés par BaseMasterPageles classes dérivées (Site.master et Alternate.master). Ce type d’héritage est possible en marquant la classe et ses membres comme abstract. En bref, l’ajout du abstract mot clé à ces deux membres annonce qu’il BaseMasterPage n’a pas implémenté RefreshRecentProductsGrid et GridMessageText, mais que ses classes dérivées seront.

Nous devons également définir l’événement PricesDoubled et BaseMasterPage fournir un moyen par les classes dérivées pour déclencher l’événement. Le modèle utilisé dans .NET Framework pour faciliter ce comportement consiste à créer un événement public dans la classe de base et à ajouter une méthode protégée virtual nommée OnEventName. Les classes dérivées peuvent ensuite appeler cette méthode pour déclencher l’événement ou la remplacer pour exécuter du code immédiatement avant ou après le levée de l’événement.

Mettez à jour votre BaseMasterPage classe afin qu’elle contienne le code suivant :

using System; public abstract class BaseMasterPage : System.Web.UI.MasterPage
{ 
    public event EventHandler PricesDoubled; 
    protected virtual void OnPricesDoubled(EventArgs e) 
    { 
        if (PricesDoubled != null) 
        PricesDoubled(this, e); 
    } 
    public abstract void RefreshRecentProductsGrid();
    public abstract string GridMessageText 
    { 
        get; 
        set; 
    } 
}

Ensuite, accédez à la classe code-behind et faites-en Site.master dériver BaseMasterPage. Parce que BaseMasterPage nous devons remplacer ces abstract membres ici en Site.master.abstract Ajoutez le override mot clé aux définitions de méthode et de propriété. Mettez également à jour le code qui déclenche l’événement PricesDoubled dans le DoublePrice gestionnaire d’événements de Click Button avec un appel à la méthode de la classe de OnPricesDoubled base.

Après ces modifications, la Site.master classe code-behind doit contenir le code suivant :

public partial class Site : BaseMasterPage { 
    protected void Page_Load(object sender, EventArgs e) 
    { 
        DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd"); 
    } 
    public override void RefreshRecentProductsGrid()
    { 
        RecentProducts.DataBind();
    } 
    public override string GridMessageText
    { 
        get 
        {
            return GridMessage.Text;
        } 
        set
        {
            GridMessage.Text = value; 
        } 
    }
    protected void DoublePrice_Click(object sender, EventArgs e) 
    { 
        // Double the prices 
        DoublePricesDataSource.Update();
        // Refresh RecentProducts 
        RecentProducts.DataBind();
        // Raise the PricesDoubled event
        base.OnPricesDoubled(EventArgs.Empty);
    } 
}

Nous devons également mettre à jour Alternate.masterla classe code-behind pour dériver BaseMasterPage et remplacer les deux abstract membres. Toutefois, étant donné que Alternate.master ne contient pas de GridView qui répertorie les produits les plus récents ni une étiquette qui affiche un message après l’ajout d’un nouveau produit à la base de données, ces méthodes n’ont rien à faire.

public partial class Alternate : BaseMasterPage 
{ 
    public override void RefreshRecentProductsGrid() 
    { 
        // Do nothing 
    } 
    public override string GridMessageText 
    { 
        get
        { 
            return string.Empty;
        } 
        set
        {
            // Do nothing 
        } 
    }
}

Référencement de la classe de page maître de base

Maintenant que nous avons terminé la BaseMasterPage classe et que nos deux pages maîtres l’étendent, notre dernière étape consiste à mettre à jour les ~/Admin/AddProduct.aspx pages et ~/Admin/Products.aspx à faire référence à ce type commun. Commencez par modifier la @MasterType directive dans les deux pages à partir de :

<%@ MasterType VirtualPath="~/Site.master" %>

Par :

<%@ MasterType TypeName="BaseMasterPage" %>

Au lieu de référencer un chemin d’accès de fichier, la @MasterType propriété fait désormais référence au type de base (BaseMasterPage). Par conséquent, la propriété fortement typée Master utilisée dans les classes code-behind des deux pages est désormais de type BaseMasterPage (au lieu du type Site). Avec ce changement en place revisiter ~/Admin/Products.aspx. Auparavant, cela entrait une erreur de conversion, car la page est configurée pour utiliser la Alternate.master page maître, mais la @MasterType directive a référencé le Site.master fichier. Mais maintenant, la page s’affiche sans erreur. Cela est dû au fait que la Alternate.master page maître peut être convertie en objet de type BaseMasterPage (car elle l’étend).

Il y a une petite modification qui doit être apportée dans ~/Admin/AddProduct.aspx. Le gestionnaire d’événements du ItemInserted contrôle DetailsView utilise à la fois la propriété fortement typée Master et la propriété faiblement typée Page.Master . Nous avons résolu la référence fortement typée lorsque nous avons mis à jour la @MasterType directive, mais nous devons quand même mettre à jour la référence faiblement typée. Remplacez la ligne de code suivante :

Site myMasterPage = Page.Master as Site;

Avec les éléments suivants, qui sont convertis Page.Master en type de base :

BaseMasterPage myMasterPage = Page.Master as BaseMasterPage;

Étape 4 : Détermination de la page maître à lier aux pages de contenu

Notre BasePage classe définit actuellement les propriétés de toutes les pages de MasterPageFile contenu sur une valeur codée en dur dans l’étape PreInit du cycle de vie de la page. Nous pouvons mettre à jour ce code pour baser la page maître sur un facteur externe. La page maître à charger dépend peut-être des préférences de l’utilisateur actuellement connecté. Dans ce cas, nous aurions besoin d’écrire du code dans la OnPreInit méthode qui BasePage recherche les préférences de page maître de l’utilisateur actuellement en visite.

Nous allons créer une page web qui permet à l’utilisateur de choisir la page maître à utiliser - Site.master ou Alternate.master - et d’enregistrer ce choix dans une variable de session. Commencez par créer une page web dans le répertoire racine nommé ChooseMasterPage.aspx. Lorsque vous créez cette page (ou toute autre page de contenu désormais), vous n’avez pas besoin de la lier à une page maître, car la page maître est définie par programmation dans BasePage. Toutefois, si vous ne liez pas la nouvelle page à une page maître, le balisage déclaratif par défaut de la nouvelle page contient un formulaire web et d’autres contenus fournis par la page maître. Vous devez remplacer manuellement ce balisage par les contrôles de contenu appropriés. Pour cette raison, il est plus facile de lier la nouvelle page ASP.NET à une page maître.

Remarque

Étant donné que Site.master le Alternate.master même ensemble de contrôles ContentPlaceHolder n’a pas d’importance pour la page maître que vous choisissez lors de la création de la page de contenu. Pour une cohérence, je suggère d’utiliser Site.master.

Ajouter une nouvelle page de contenu au site web

Figure 05 : Ajouter une nouvelle page de contenu au site web (cliquez pour afficher l’image de taille complète)

Mettez à jour le Web.sitemap fichier pour inclure une entrée pour cette leçon. Ajoutez le balisage suivant sous les <siteMapNode> pages maîtres et ASP.NET leçon AJAX :

<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />

Avant d’ajouter du contenu à la ChooseMasterPage.aspx page, prenez un moment pour mettre à jour la classe code-behind de la page afin qu’elle dérive ( BasePage plutôt que System.Web.UI.Page). Ensuite, ajoutez un contrôle DropDownList à la page, définissez sa ID propriété MasterPageChoicesur , puis ajoutez deux ListItems avec les Text valeurs « ~/Site.master » et « ~/Alternate.master ».

Ajoutez un contrôle Web Button à la page et définissez ses ID Text propriétés SaveLayout sur et « Enregistrer le choix de disposition », respectivement. À ce stade, le balisage déclaratif de votre page doit ressembler à ce qui suit :

<p> 
 Your layout choice: 
 <asp:DropDownList ID="MasterPageChoice" runat="server"> 
 <asp:ListItem>~/Site.master</asp:ListItem>
 <asp:ListItem>~/Alternate.master</asp:ListItem>
 </asp:DropDownList> 
</p> 
<p> 
 <asp:Button ID="SaveLayout" runat="server" Text="Save Layout Choice" /> 
</p>

Lorsque la page est d’abord visitée, nous devons afficher le choix de page maître actuellement sélectionné par l’utilisateur. Créez un gestionnaire d’événements Page_Load et ajoutez le code suivant :

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
        if (Session["MyMasterPage"] != null)
        {
            ListItem li = MasterPageChoice.Items.FindByText(Session["MyMasterPage"].ToString());
            if (li != null) 
                li.Selected = true; 
        } 
    }
}

Le code ci-dessus s’exécute uniquement sur la première visite de page (et non sur les publications ultérieures). Il vérifie d’abord si la variable MyMasterPage de session existe. Si c’est le cas, il tente de trouver l’objet ListItem correspondant dans la MasterPageChoice liste déroulante. Si un ListItem correspondant est trouvé, sa Selected propriété est définie sur true.

Nous avons également besoin de code qui enregistre le choix de l’utilisateur dans la MyMasterPage variable session. Créez un gestionnaire d’événements pour l’événement SaveLayout de Click Button et ajoutez le code suivant :

protected void SaveLayout_Click(object sender, EventArgs e)
{
    Session["MyMasterPage"] = MasterPageChoice.SelectedValue;
    Response.Redirect("ChooseMasterPage.aspx"); 
}

Remarque

Au moment où le Click gestionnaire d’événements s’exécute à la publication, la page maître a déjà été sélectionnée. Par conséquent, la sélection de la liste déroulante de l’utilisateur ne sera pas en vigueur tant que la page suivante n’est pas visitée. Force Response.Redirect le navigateur à re-demander ChooseMasterPage.aspx.

Une fois la ChooseMasterPage.aspx page terminée, notre tâche finale consiste à BasePage affecter la MasterPageFile propriété en fonction de la valeur de la MyMasterPage variable Session. Si la variable de session n’est pas définie, la BasePage valeur par défaut Site.masterest .

protected override void OnPreInit(EventArgs e) 
{ 
    SetMasterPageFile();
    base.OnPreInit(e); 
} 
protected virtual void SetMasterPageFile()
{ 
    this.MasterPageFile = GetMasterPageFileFromSession();
} 
protected string GetMasterPageFileFromSession() 
{ 
    if (Session["MyMasterPage"] == null) 
        return "~/Site.master";
    else
        return Session["MyMasterPage"].ToString(); 
}

Remarque

J’ai déplacé le code qui affecte la propriété de MasterPageFile l’objet Page hors du OnPreInit gestionnaire d’événements et dans deux méthodes distinctes. Cette première méthode, affecte SetMasterPageFilela MasterPageFile propriété à la valeur retournée par la deuxième méthode. GetMasterPageFileFromSession J’ai fait la SetMasterPageFile méthode virtual afin que les futures classes qui s’étendent BasePage puissent éventuellement la remplacer pour implémenter une logique personnalisée, si nécessaire. Nous allons voir un exemple de substitution BasePagede la propriété de 's SetMasterPageFile dans le tutoriel suivant.

Avec ce code en place, visitez la ChooseMasterPage.aspx page. Initialement, la Site.master page maître est sélectionnée (voir la figure 6), mais l’utilisateur peut choisir une autre page maître dans la liste déroulante.

Les pages de contenu sont affichées à l’aide de la page maître Site.master

Figure 06 : Les pages de contenu sont affichées à l’aide de la page maître (cliquez pour afficher l’image Site.masterde taille complète)

Les pages de contenu sont désormais affichées à l’aide de la page maître Alternate.master

Figure 07 : Les pages de contenu sont désormais affichées à l’aide de la Alternate.master page maître (cliquez pour afficher l’image de taille complète)

Résumé

Lorsqu’une page de contenu est visitée, ses contrôles de contenu sont fusionnés avec les contrôles ContentPlaceHolder de sa page maître. La page maître de la page de contenu est indiquée par la propriété de MasterPageFile la Page classe, qui est affectée à l’attribut de MasterPageFile la @Page directive pendant l’étape d’initialisation. Comme le montre ce tutoriel, nous pouvons affecter une valeur à la MasterPageFile propriété tant que nous le faisons avant la fin de l’étape PreInit. La possibilité de spécifier par programmation la page maître ouvre la porte pour des scénarios plus avancés, tels que la liaison dynamique d’une page de contenu à une page maître en fonction de facteurs externes.

Bonne programmation !

Pour aller plus loin

Pour plus d’informations sur les sujets abordés dans ce tutoriel, consultez les ressources suivantes :

À propos de l’auteur

Scott Mitchell, auteur de plusieurs livres ASP/ASP.NET et fondateur de 4GuysFromRolla.com, travaille avec les technologies Web Microsoft depuis 1998. Scott travaille en tant que consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 3,5 en 24 heures. Scott peut être accessible à l’adresse mitchell@4GuysFromRolla.com ou via son blog à .http://ScottOnWriting.NET

Merci spécial à

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Le réviseur principal de ce tutoriel était Suchi Banerjee. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com