Programmgesteuertes Festlegen der Masterseite (VB)
von Scott Mitchell
Hier erfahren Sie, wie Sie die master Seite der Inhaltsseite programmgesteuert über den PreInit-Ereignishandler festlegen.
Einführung
Seit dem ersten Beispiel in Erstellen eines Site-Wide Layouts mithilfe von Gestaltungsvorlagen haben alle Inhaltsseiten über das -Attribut in der @Page
-Direktive deklarativ auf ihre MasterPageFile
master Seite verwiesen. Die folgende @Page
Direktive verknüpft z. B. die Inhaltsseite mit der master SeiteSite.master
:
<%@ Page Language="C#" MasterPageFile="~/Site.master"... %>
Die Page
-Klasse im System.Web.UI
Namespace enthält eine MasterPageFile
-Eigenschaft, die den Pfad zur master Seite der Inhaltsseite zurückgibt. Diese Eigenschaft wird von der @Page
-Direktive festgelegt. Diese Eigenschaft kann auch verwendet werden, um die master Seite der Inhaltsseite programmgesteuert anzugeben. Dieser Ansatz ist nützlich, wenn Sie die master Seite basierend auf externen Faktoren dynamisch zuweisen möchten, z. B. der Benutzer, der die Seite besucht.
In diesem Tutorial fügen wir unserer Website eine zweite master-Seite hinzu und entscheiden dynamisch, welche master Seite zur Laufzeit verwendet werden soll.
Schritt 1: Ein Blick auf den Seitenlebenszyklus
Wenn beim Webserver eine Anforderung für eine ASP.NET Seite eingeht, bei der es sich um eine Inhaltsseite handelt, muss die ASP.NET-Engine die Inhaltssteuerelemente der Seite mit den entsprechenden ContentPlaceHolder-Steuerelementen der master Seite verschmelzen. Durch diese Fusion wird eine einzelne Steuerungshierarchie erstellt, die dann den typischen Seitenlebenszyklus durchlaufen kann.
Abbildung 1 veranschaulicht diese Fusion. Schritt 1 in Abbildung 1 zeigt die anfänglichen Inhalts- und master Seitensteuerungshierarchien. Am Ende der PreInit-Phase werden die Inhaltssteuerelemente auf der Seite den entsprechenden ContentPlaceHolders auf der Seite master hinzugefügt (Schritt 2). Nach dieser Fusion dient die Seite master als Stamm der Fusionssteuerelementhierarchie. Diese fusionierte Steuerelementhierarchie wird dann der Seite hinzugefügt, um die fertige Steuerungshierarchie zu erstellen (Schritt 3). Das Ergebnis ist, dass die Steuerelementhierarchie der Seite die Hierarchie der fusionierten Steuerelemente enthält.
Abbildung 01: Die Gestaltungsvorlage und die Steuerelementhierarchien der Inhaltsseite werden während der PreInit-Phase miteinander verschmolzen (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Schritt 2: Festlegen derMasterPageFile
Eigenschaft über Code
Welche master Seite an dieser Fusion beteiligt ist, hängt vom Wert der Page
Eigenschaft des MasterPageFile
Objekts ab. Das Festlegen des MasterPageFile
Attributs in der @Page
-Direktive hat den Nettoeffekt, dass die Page
-Eigenschaft der - MasterPageFile
Eigenschaft während der Initialisierungsphase zugewiesen wird, die die erste Phase des Lebenszyklus der Seite ist. Alternativ können wir diese Eigenschaft programmgesteuert festlegen. Es ist jedoch zwingend erforderlich, dass diese Eigenschaft festgelegt wird, bevor die Fusion in Abbildung 1 erfolgt.
Am Anfang der PreInit-Phase löst das Page
Objekt sein PreInit
-Ereignis aus und ruft seine OnPreInit
-Methode auf. Um die master Seite programmgesteuert festzulegen, können wir dann entweder einen Ereignishandler für das PreInit
Ereignis erstellen oder die OnPreInit
-Methode überschreiben. Sehen wir uns beide Ansätze an.
Öffnen Default.aspx.vb
Sie zunächst die CodeBehind-Klassendatei für die Homepage unserer Website. Fügen Sie einen Ereignishandler für das Ereignis der Seite PreInit
hinzu, indem Sie den folgenden Code eingeben:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
End Sub
Hier können wir die MasterPageFile
-Eigenschaft festlegen. Aktualisieren Sie den Code, sodass er den Wert "~/Site. master" an die MasterPageFile
-Eigenschaft.
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.MasterPageFile = "~/Site.master"
End Sub
Wenn Sie einen Haltepunkt festlegen und mit dem Debuggen beginnen, sehen Sie, dass der Default.aspx
Ereignishandler ausgeführt wird und die MasterPageFile
Eigenschaft "~/Site.master" zugewiesen wird.Page_PreInit
Alternativ können Sie die -Methode der Page
-Klasse OnPreInit
überschreiben und die MasterPageFile
-Eigenschaft dort festlegen. In diesem Beispiel legen wir nicht die master Seite auf einer bestimmten Seite fest, sondern aus BasePage
. Denken Sie daran, dass wir im Tutorial Angeben von Titeln, Metatags und anderen HTML-Headern im Gestaltungsvorlagen-Tutorial eine benutzerdefinierte Basisseitenklasse (BasePage
) erstellt haben. Überschreibt derzeit BasePage
die -Methode der Page
-Klasse OnLoadComplete
, in der die -Eigenschaft der Seite Title
basierend auf den Siteübersichtsdaten festgelegt wird. Lassen Sie uns aktualisierenBasePage
, um auch die OnPreInit
-Methode außer Kraft zu setzen, um die master Seite programmgesteuert anzugeben.
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
Me.MasterPageFile = "~/Site.master"
MyBase.OnPreInit(e)
End Sub
Da alle unsere Inhaltsseiten von BasePage
abgeleitet sind, wird ihnen jetzt die master Seite programmgesteuert zugewiesen. An diesem Punkt ist der PreInit
Ereignishandler in Default.aspx.vb
überflüssig. Sie können ihn entfernen.
Was ist mit der@Page
Richtlinie?
Etwas verwirrend ist, dass die Eigenschaften der Inhaltsseiten MasterPageFile
jetzt an zwei Stellen angegeben werden: programmgesteuert in der -Methode der BasePage
Klasse OnPreInit
sowie über das -Attribut in der MasterPageFile
-Direktive jeder Inhaltsseite @Page
.
Die erste Phase im Seitenlebenszyklus ist die Initialisierungsphase. Während dieser Phase wird der Page
-Eigenschaft des MasterPageFile
Objekts der Wert des MasterPageFile
Attributs in der @Page
-Direktive zugewiesen (sofern angegeben). Die PreInit-Phase folgt der Initialisierungsphase, und hier legen wir die Eigenschaft des Page
MasterPageFile
Objekts programmgesteuert fest, wodurch der aus der @Page
-Direktive zugewiesene Wert überschrieben wird. Da wir die Page
Eigenschaft des MasterPageFile
Objekts programmgesteuert festlegen, können wir das Attribut aus der MasterPageFile
@Page
-Direktive entfernen, ohne die Benutzererfahrung des Endbenutzers zu beeinträchtigen. Um sich davon zu überzeugen, entfernen Sie das Attribut aus der MasterPageFile
@Page
Direktive in Default.aspx
und besuchen Sie die Seite dann über einen Browser. Wie Sie erwarten würden, ist die Ausgabe die gleiche wie vor dem Entfernen des Attributs.
Ob die MasterPageFile
Eigenschaft über die @Page
-Direktive festgelegt wird oder programmgesteuert festgelegt wird, ist für die Endbenutzererfahrung nicht relevant. Das MasterPageFile
Attribut in der @Page
-Direktive wird jedoch von Visual Studio während der Entwurfszeit verwendet, um die WYSIWYG-Ansicht im Designer zu erstellen. Wenn Sie in Visual Studio zu Default.aspx
zurückkehren und zum Designer wird die Meldung "Gestaltungsvorlagenfehler: Die Seite verfügt über Steuerelemente, die einen Gestaltungsvorlagenverweis erfordern, aber keines angegeben ist" (siehe Abbildung 2).
Kurz gesagt, Sie müssen das MasterPageFile
Attribut in der @Page
-Direktive belassen, um eine umfassende Entwurfszeiterfahrung in Visual Studio zu genießen.
@Page-Direktive , um die Entwurfsansicht zu rendern" />
Abbildung 02: Visual Studio Verwendet das Attribut der @Page
Direktive MasterPageFile
, um die Entwurfsansicht zu rendern (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Schritt 3: Erstellen einer alternativen Gestaltungsvorlage
Da die master Seite einer Inhaltsseite programmgesteuert zur Laufzeit festgelegt werden kann, ist es möglich, eine bestimmte master Seite basierend auf einigen externen Kriterien dynamisch zu laden. Diese Funktionalität kann in Situationen nützlich sein, in denen das Layout der Website je nach Benutzer variieren muss. Für instance kann eine Webanwendung der Blog-Engine benutzern erlauben, ein Layout für ihren Blog auszuwählen, wobei jedes Layout einer anderen master Seite zugeordnet ist. Wenn ein Besucher den Blog eines Benutzers anzeigt, muss die Webanwendung zur Laufzeit das Layout des Blogs bestimmen und die entsprechende master Seite dynamisch der Inhaltsseite zuordnen.
Sehen wir uns an, wie eine master Seite zur Laufzeit basierend auf einigen externen Kriterien dynamisch geladen wird. Unsere Website enthält derzeit nur eine master Seite (Site.master
). Wir benötigen eine weitere master Seite, um die Auswahl einer master Seite zur Laufzeit zu veranschaulichen. Dieser Schritt konzentriert sich auf das Erstellen und Konfigurieren der neuen seite master. Schritt 4 befasst sich mit dem Bestimmen, welche master Seite zur Laufzeit verwendet werden soll.
Erstellen Sie eine neue seite master im Stammordner namens Alternate.master
. Fügen Sie der Website außerdem ein neues Stylesheet mit dem Namen AlternateStyles.css
hinzu.
Abbildung 03: Hinzufügen einer weiteren Gestaltungsvorlage und einer CSS-Datei zur Website (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Ich habe die Alternate.master
master Seite so entworfen, dass der Titel oben auf der Seite zentriert und auf einem Marinehintergrund angezeigt wird. Ich habe die linke Spalte ausgegeben und diesen Inhalt unter das MainContent
ContentPlaceHolder-Steuerelement verschoben, das sich jetzt über die gesamte Breite der Seite erstreckt. Darüber hinaus habe ich die ungeordnete Lektionsliste gelöscht und sie durch eine horizontale Liste oberhalb MainContent
von ersetzt. Ich habe auch die Schriftarten und Farben aktualisiert, die von der master Seite verwendet werden (und damit auch deren Inhaltsseiten). Abbildung 4 zeigt Default.aspx
die Verwendung der Alternate.master
seite master.
Hinweis
ASP.NET umfasst die Möglichkeit, Designs zu definieren. Ein Design ist eine Sammlung von Bildern, CSS-Dateien und stilbezogenen Websteuerelementeigenschafteneinstellungen, die zur Laufzeit auf eine Seite angewendet werden können. Designs sind der weg, wenn sich die Layouts Ihrer Website nur in den angezeigten Bildern und ihren CSS-Regeln unterscheiden. Wenn sich die Layouts wesentlich unterscheiden, z. B. bei Verwendung verschiedener Websteuerelemente oder eines grundlegend anderen Layouts, müssen Sie separate master Seiten verwenden. Weitere Informationen zu Designs finden Sie im Abschnitt Weiterführende Lektüre am Ende dieses Tutorials.
Abbildung 04: Unsere Inhaltsseiten können jetzt ein neues Erscheinungsbild verwenden (Klicken Sie hier, um ein Bild in voller Größe anzuzeigen)
Wenn die master und das Inhaltsseiten-Markup verschmolzen sind, überprüft die MasterPage
Klasse, ob jedes Content-Steuerelement auf der Inhaltsseite auf einen ContentPlaceHolder in der master Seite verweist. Eine Ausnahme wird ausgelöst, wenn ein Content-Steuerelement gefunden wird, das auf einen nicht vorhandenen ContentPlaceHolder verweist. Anders ausgedrückt: Es ist zwingend erforderlich, dass die master Seite, die der Inhaltsseite zugewiesen wird, über einen ContentPlaceHolder für jedes Inhaltssteuerelement auf der Inhaltsseite verfügt.
Die Site.master
Seite master enthält vier ContentPlaceHolder-Steuerelemente:
head
MainContent
QuickLoginUI
LeftColumnContent
Einige der Inhaltsseiten unserer Website enthalten nur ein oder zwei Inhaltssteuerelemente; andere enthalten ein Content-Steuerelement für jeden der verfügbaren ContentPlaceHolders. Wenn unsere neue master Seite (Alternate.master
) jemals den Inhaltsseiten zugewiesen werden kann, die Inhaltssteuerelemente für alle ContentPlaceHolders enthaltenSite.master
, ist es wichtig, dass Alternate.master
auch die gleichen ContentPlaceHolder-Steuerelemente wie Site.master
enthalten.
Damit Ihre Alternate.master
master Seite meiner ähnelt (siehe Abbildung 4), definieren Sie zunächst die Formatvorlagen der master Seite im AlternateStyles.css
Stylesheet. Fügen Sie die folgenden Regeln in hinzu 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;
}
Fügen Sie als Nächstes das folgende deklarative Markup zu hinzu Alternate.master
. Wie Sie sehen können, Alternate.master
enthält vier ContentPlaceHolder-Steuerelemente mit denselben ID
Werten wie die ContentPlaceHolder-Steuerelemente in Site.master
. Darüber hinaus enthält es ein ScriptManager-Steuerelement, das für die Seiten auf unserer Website erforderlich ist, die das ASP.NET AJAX-Framework verwenden.
<!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>
Testen der neuen Gestaltungsvorlage
Zum Testen dieses neuen master Seite die -Methode der BasePage
Klasse OnPreInit
aktualisieren, sodass der MasterPageFile
-Eigenschaft der Wert "~/Alternate.maser"
zugewiesen wird, und besuchen Sie dann die Website. Jede Seite sollte ohne Fehler funktionieren, mit Ausnahme von zwei: ~/Admin/AddProduct.aspx
und ~/Admin/Products.aspx
. Das Hinzufügen eines Produkts zur DetailsView in ~/Admin/AddProduct.aspx
führt zu einer NullReferenceException
aus der Codezeile, die versucht, die Eigenschaft der master Seite GridMessageText
festzulegen. Beim Aufrufen ~/Admin/Products.aspx
eines InvalidCastException
wird beim Laden der Seite die Meldung ausgelöst: "Objekt vom Typ 'ASP.alternate_master' kann nicht in den Typ 'ASP.site_master' umgewandelt werden."
Diese Fehler treten auf, weil die Site.master
CodeBehind-Klasse öffentliche Ereignisse, Eigenschaften und Methoden enthält, die nicht in Alternate.master
definiert sind. Der Markupteil dieser beiden Seiten verfügt über eine @MasterType
Direktive, die auf die Site.master
master Seite verweist.
<%@ MasterType VirtualPath="~/Site.master" %>
Außerdem enthält der DetailsView-Ereignishandler ItemInserted
in ~/Admin/AddProduct.aspx
Code, der die lose typisierte Eigenschaft in ein Objekt vom Typ Site
umformtPage.Master
. Die @MasterType
-Direktive (auf diese Weise verwendet) und die Umwandlung im ItemInserted
Ereignishandler koppeln die ~/Admin/AddProduct.aspx
Seiten und ~/Admin/Products.aspx
eng mit der Site.master
master Seite.
Um diese enge Kopplung zu durchbrechen, können wir eine gemeinsame Basisklasse haben Site.master
und Alternate.master
daraus ableiten, die Definitionen für die öffentlichen Member enthält. Anschließend können wir die @MasterType
Direktive so aktualisieren, dass sie auf diesen allgemeinen Basistyp verweist.
Erstellen einer benutzerdefinierten Basismasterseitenklasse
Fügen Sie dem Ordner eine neue Klassendatei mit dem App_Code
Namen BaseMasterPage.vb
hinzu, und lassen Sie sie von ableiten System.Web.UI.MasterPage
. Wir müssen die RefreshRecentProductsGrid
Methode und die GridMessageText
Eigenschaft in BaseMasterPage
definieren, aber wir können sie nicht einfach von Site.master
dorthin verschieben, da diese Member mit Websteuerelementen arbeiten, die für die Site.master
master Seite (RecentProducts
GridView und GridMessage
Label) spezifisch sind.
Was wir tun müssen, ist so zu konfigurieren BaseMasterPage
, dass diese Member dort definiert sind, aber tatsächlich von den abgeleiteten BaseMasterPage
Klassen (Site.master
und Alternate.master
) implementiert werden. Diese Art der Vererbung ist möglich, indem die Klasse als MustInherit
und ihre Member als MustOverride
gekennzeichnet werden. Kurz gesagt, das Hinzufügen dieser Schlüsselwörter zur Klasse und ihren beiden Membern gibt an, dass BaseMasterPage
und nicht implementiert RefreshRecentProductsGrid
wurde, GridMessageText
sondern dass die abgeleiteten Klassen dies geschieht.
Außerdem müssen wir das PricesDoubled
Ereignis in BaseMasterPage
definieren und von den abgeleiteten Klassen ein Mittel bereitstellen, um das Ereignis auszulösen. Das Muster, das in der .NET Framework verwendet wird, um dieses Verhalten zu erleichtern, besteht darin, ein öffentliches Ereignis in der Basisklasse zu erstellen und eine geschützte, überschreibbare Methode namens OnEventName
hinzuzufügen. Abgeleitete Klassen können dann diese Methode aufrufen, um das Ereignis auszulösen, oder es überschreiben, um Code unmittelbar vor oder nach dem Auslösen des Ereignisses auszuführen.
Aktualisieren Sie Ihre BaseMasterPage
Klasse so, dass sie den folgenden Code enthält:
Public MustInherit Class BaseMasterPage
Inherits System.Web.UI.MasterPage
Public Event PricesDoubled As EventHandler
Protected Overridable Sub OnPricesDoubled(ByVal e As EventArgs)
RaiseEvent PricesDoubled(Me, e)
End Sub
Public MustOverride Sub RefreshRecentProductsGrid()
Public MustOverride Property GridMessageText() As String
End Class
Wechseln Sie als Nächstes Site.master
zur CodeBehind-Klasse, und lassen Sie sie von abgeleitet werden BaseMasterPage
. Da BaseMasterPage
elemente enthalten, die markiert sind MustOverride
, müssen wir diese Member hier in Site.master
überschreiben. Fügen Sie die Overrides
Schlüsselwort (keyword) den Methoden- und Eigenschaftsdefinitionen hinzu. Aktualisieren Sie außerdem den Code, der das PricesDoubled
Ereignis im Ereignishandler der DoublePrice
Schaltfläche Click
auslöst, mit einem Aufruf der -Methode der Basisklasse OnPricesDoubled
.
Nach diesen Änderungen sollte die Site.master
CodeBehind-Klasse den folgenden Code enthalten:
Partial Class Site
Inherits BaseMasterPage
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd")
End Sub
Public Overrides Sub RefreshRecentProductsGrid()
RecentProducts.DataBind()
End Sub
Public Overrides Property GridMessageText() As String
Get
Return GridMessage.Text
End Get
Set(ByVal Value As String)
GridMessage.Text = Value
End Set
End Property
Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
' Double the prices
DoublePricesDataSource.Update()
' Refresh RecentProducts
RecentProducts.DataBind()
' Raise the PricesDoubled event
MyBase.OnPricesDoubled(EventArgs.Empty)
End Sub
End Class
Außerdem muss die CodeBehind-Klasse aktualisiert Alternate.master
werden, damit sie von BaseMasterPage
den beiden MustOverride
Membern abgeleitet und überschrieben wird. Da Alternate.master
jedoch keine GridView enthält, die die neuesten Produkte auflistet, noch ein Label, das eine Meldung anzeigt, nachdem ein neues Produkt der Datenbank hinzugefügt wurde, müssen diese Methoden nichts tun.
Partial Class Alternate
Inherits BaseMasterPage
Public Overrides Property GridMessageText() As String
Get
Return String.Empty
End Get
Set(ByVal value As String)
' Do nothing
End Set
End Property
Public Overrides Sub RefreshRecentProductsGrid()
' Do nothing
End Sub
End Class
Verweisen auf die Masterpage-Basisklasse
Nachdem wir nun die BaseMasterPage
Klasse abgeschlossen haben und unsere beiden master Seiten erweitert haben, besteht unser letzter Schritt darin, die ~/Admin/AddProduct.aspx
Seiten und ~/Admin/Products.aspx
so zu aktualisieren, dass sie auf diesen allgemeinen Typ verweisen. Beginnen Sie mit dem Ändern der @MasterType
Direktive auf beiden Seiten von:
<%@ MasterType VirtualPath="~/Site.master" %>
Nach:
<%@ MasterType TypeName="BaseMasterPage" %>
Anstatt auf einen Dateipfad zu verweisen, verweist die @MasterType
-Eigenschaft jetzt auf den Basistyp (BaseMasterPage
). Folglich ist die stark typisierte Master
Eigenschaft, die in den CodeBehind-Klassen beider Seiten verwendet wird, jetzt vom Typ BaseMasterPage
(anstelle des Typs Site
). Mit dieser Änderung können Sie erneut besuchen ~/Admin/Products.aspx
. Zuvor hat dies zu einem Umwandlungsfehler geführt, da die Seite für die Verwendung der Alternate.master
master-Seite konfiguriert ist, aber die @MasterType
Direktive auf die Site.master
Datei verweist. Aber jetzt wird die Seite ohne Fehler gerendert. Dies liegt daran, dass die Alternate.master
master Seite in ein Objekt vom Typ BaseMasterPage
umgewandelt werden kann (da es erweitert wird).
Es gibt eine kleine Änderung, die in ~/Admin/AddProduct.aspx
vorgenommen werden muss. Der Ereignishandler des ItemInserted
DetailsView-Steuerelements verwendet sowohl die stark typisierte Master
Eigenschaft als auch die lose typisierte Page.Master
Eigenschaft. Wir haben den stark typisierten Verweis behoben, als wir die @MasterType
Direktive aktualisiert haben, aber wir müssen den lose typisierten Verweis trotzdem aktualisieren. Ersetzen Sie die folgende Codezeile:
Dim myMasterPage As Site = CType(Page.Master, Site)
Mit folgendem , der in den Basistyp umgewandelt Page.Master
wird:
Dim myMasterPage As BaseMasterPage = CType(Page.Master, BaseMasterPage)
Schritt 4: Bestimmen, welche Gestaltungsvorlage an die Inhaltsseiten gebunden werden soll
Unsere BasePage
Klasse legt derzeit die Eigenschaften aller Inhaltsseiten MasterPageFile
auf einen hartcodierten Wert in der PreInit-Phase des Seitenlebenszyklus fest. Wir können diesen Code aktualisieren, um die master Seite auf einem externen Faktor zu basieren. Möglicherweise hängt die zu ladende master Seite von den Einstellungen des aktuell angemeldeten Benutzers ab. In diesem Fall müssen wir Code in die -Methode BasePage
schreiben, die OnPreInit
die derzeit besuchten Benutzereinstellungen für master Seite sucht.
Erstellen Sie eine Webseite, auf der der Benutzer auswählen kann, welche master Seite oder verwendet Site.master
Alternate.master
werden soll, und diese Auswahl in einer Sitzungsvariablen speichern kann. Erstellen Sie zunächst eine neue Webseite im Stammverzeichnis mit dem Namen ChooseMasterPage.aspx
. Beim Erstellen dieser Seite (oder anderer Inhaltsseiten) müssen Sie sie nicht an eine master Seite binden, da die master Seite programmgesteuert in BasePage
festgelegt wird. Wenn Sie die neue Seite jedoch nicht an eine master Seite binden, enthält das standardmäßige deklarative Markup der neuen Seite ein Webformular und andere Inhalte, die von der master Seite bereitgestellt werden. Sie müssen dieses Markup manuell durch die entsprechenden Inhaltssteuerelemente ersetzen. Aus diesem Grund finde ich es einfacher, die neue ASP.NET Seite an eine master Seite zu binden.
Hinweis
Da Site.master
und Alternate.master
über denselben Satz von ContentPlaceHolder-Steuerelementen verfügen, spielt es keine Rolle, welche master Seite Sie beim Erstellen der neuen Inhaltsseite auswählen. Aus Gründen der Konsistenz würde ich vorschlagen, die Verwendung von zu verwenden Site.master
.
Abbildung 05: Hinzufügen einer neuen Inhaltsseite zur Website (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Aktualisieren Sie die Web.sitemap
Datei so, dass sie einen Eintrag für diese Lektion enthält. Fügen Sie das folgende Markup unter der <siteMapNode>
für die Gestaltungsvorlagen und ASP.NET AJAX-Lektion hinzu:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
Bevor Sie der ChooseMasterPage.aspx
Seite Inhalte hinzufügen, nehmen Sie sich einen Moment Zeit, um die CodeBehind-Klasse der Seite zu aktualisieren, sodass sie von (statt System.Web.UI.Page
) BasePage
abgeleitet wird. Fügen Sie als Nächstes der Seite ein DropDownList-Steuerelement hinzu, legen Sie dessen ID
Eigenschaft auf MasterPageChoice
fest, und fügen Sie zwei ListItems mit den Text
Werten "~/Site.master" und "~/Alternate.master" hinzu.
Fügen Sie der Seite ein Button-Websteuerelement hinzu, und legen Sie dessen ID
Eigenschaften und Text
auf SaveLayout
bzw. "Layoutauswahl speichern" fest. An diesem Punkt sollte das deklarative Markup Ihrer Seite wie folgt aussehen:
<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>
Wenn die Seite zum ersten Mal besucht wird, müssen wir die aktuell ausgewählte Master Seitenauswahl des Benutzers anzeigen. Erstellen Sie einen Page_Load
Ereignishandler, und fügen Sie den folgenden Code hinzu:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
If Session("MyMasterPage") IsNot Nothing Then
Dim li As ListItem = MasterPageChoice.Items.FindByText(Session("MyMasterPage").ToString())
If li IsNot Nothing Then
li.Selected = True
End If
End If
End If
End Sub
Der obige Code wird nur beim ersten Seitenbesuch (und nicht bei nachfolgenden Postbacks) ausgeführt. Zuerst wird überprüft, ob die Sitzungsvariable MyMasterPage
vorhanden ist. Wenn dies der Fall ist, versucht es, das übereinstimmende ListItem in der MasterPageChoice
DropDownList zu finden. Wenn ein übereinstimmende ListItem gefunden wird, wird dessen Selected
Eigenschaft auf True
festgelegt.
Außerdem benötigen wir Code, der die Auswahl des Benutzers in der MyMasterPage
Sitzungsvariablen speichert. Erstellen Sie einen Ereignishandler für das SaveLayout
Button-Ereignis Click
, und fügen Sie den folgenden Code hinzu:
Protected Sub SaveLayout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveLayout.Click
Session("MyMasterPage") = MasterPageChoice.SelectedValue
Response.Redirect("ChooseMasterPage.aspx")
End Sub
Hinweis
Zu dem Zeitpunkt, zu dem der Click
Ereignishandler beim Postback ausgeführt wird, wurde die seite master bereits ausgewählt. Daher wird die Dropdownliste des Benutzers erst beim nächsten Seitenbesuch wirksam. Der Response.Redirect
zwingt den Browser, erneut anzufordern ChooseMasterPage.aspx
.
Nach Abschluss der ChooseMasterPage.aspx
Seite besteht unsere letzte Aufgabe darin, die -Eigenschaft basierend auf dem MasterPageFile
Wert der MyMasterPage
Session-Variablen zuzuweisenBasePage
. Wenn die Sitzungsvariable nicht festgelegt ist, ist BasePage
die Standardeinstellung auf Site.master
festgelegt.
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
SetMasterPageFile()
MyBase.OnPreInit(e)
End Sub
Protected Overridable Sub SetMasterPageFile()
Me.MasterPageFile = GetMasterPageFileFromSession()
End Sub
Protected Function GetMasterPageFileFromSession() As String
If Session("MyMasterPage") Is Nothing Then
Return "~/Site.master"
Else
Return Session("MyMasterPage").ToString()
End If
End Function
Hinweis
Ich habe den Code, der die Page
-Eigenschaft des MasterPageFile
Objekts zuweist, aus dem OnPreInit
Ereignishandler in zwei separate Methoden verschoben. Diese erste Methode weist die -Eigenschaft dem MasterPageFile
wert zu, SetMasterPageFile
der von der zweiten Methode zurückgegeben wird. GetMasterPageFileFromSession
Ich habe die SetMasterPageFile
Methode Overridable
so markiert, dass zukünftige Klassen, die erweitern BasePage
, sie optional überschreiben können, um benutzerdefinierte Logik zu implementieren, falls erforderlich. Im nächsten Tutorial sehen Sie ein Beispiel für das Überschreiben BasePage
SetMasterPageFile
der Eigenschaft.
Wenn Dieser Code vorhanden ist, besuchen Sie die ChooseMasterPage.aspx
Seite. Zunächst ist die Site.master
seite master ausgewählt (siehe Abbildung 6), aber der Benutzer kann eine andere master Seite aus der Dropdownliste auswählen.
Abbildung 06: Inhaltsseiten werden mithilfe der Gestaltungsvorlage Site.master
angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Abbildung 07: Inhaltsseiten werden jetzt mithilfe der Gestaltungsvorlage Alternate.master
angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Zusammenfassung
Wenn eine Inhaltsseite besucht wird, werden ihre Inhaltssteuerelemente mit den ContentPlaceHolder-Steuerelementen der master Seite verschmolzen. Die master Seite der Inhaltsseite wird durch die -Eigenschaft der Page
-Klasse MasterPageFile
bezeichnet, die dem Attribut der @Page
Anweisung MasterPageFile
während der Initialisierungsphase zugewiesen wird. Wie dieses Tutorial gezeigt hat, können wir der MasterPageFile
Eigenschaft einen Wert zuweisen, solange dies vor dem Ende der PreInit-Phase geschieht. Die Möglichkeit, die master Seite programmgesteuert anzugeben, öffnet die Tür für komplexere Szenarien, z. B. das dynamische Binden einer Inhaltsseite an eine master Seite basierend auf externen Faktoren.
Viel Spaß beim Programmieren!
Weitere Informationen
Weitere Informationen zu den in diesem Tutorial erläuterten Themen finden Sie in den folgenden Ressourcen:
- ASP.NET Seitenlebenszyklusdiagramm
- Übersicht über den ASP.NET-Seitenlebenszyklus
- Übersicht über ASP.NET Designs und Skins
- Gestaltungsvorlagen: Tipps, Tricks und Fallen
- Designs in ASP.NET
Zum Autor
Scott Mitchell, Autor mehrerer ASP/ASP.NET-Bücher und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 3.5 in 24 Stunden. Scott kann unter mitchell@4GuysFromRolla.com oder über seinen Blog unter http://ScottOnWriting.NETerreicht werden.
Besonderen Dank an
Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Lead Reviewer für dieses Tutorial war Suchi Banerjee. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie mir eine Zeile unter mitchell@4GuysFromRolla.com
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für