Zagnieżdżone strony wzorcowe (VB)
Autor: Scott Mitchell
Pokazuje, jak zagnieżdżać jedną stronę wzorcową w innym.
Wprowadzenie
W ciągu ostatnich dziewięciu samouczków widzieliśmy, jak zaimplementować układ całej witryny ze stronami wzorcowymi. W skrócie strony wzorcowe pozwalają nam, deweloperowi strony, zdefiniować wspólny znacznik na stronie wzorcowej wraz z określonymi regionami, które można dostosować na podstawie strony zawartości według zawartości. Kontrolki ContentPlaceHolder na stronie wzorcowej wskazują możliwe do dostosowania regiony; dostosowane znaczniki dla kontrolek ContentPlaceHolder są definiowane na stronie zawartości za pomocą kontrolek Zawartość.
Techniki strony wzorcowej, które omówiliśmy do tej pory, są doskonałe, jeśli masz jeden układ używany w całej witrynie. Jednak wiele dużych witryn internetowych ma układ witryny dostosowany w różnych sekcjach. Rozważmy na przykład aplikację opieki zdrowotnej używaną przez personel szpitala do zarządzania informacjami, działaniami i rozliczeniami pacjentów. W tej aplikacji mogą istnieć trzy typy stron internetowych:
- Strony specyficzne dla personelu, na których pracownicy mogą aktualizować dostępność, wyświetlać harmonogramy lub żądać urlopu.
- Strony specyficzne dla pacjenta, na których pracownicy wyświetlają lub edytują informacje dla określonego pacjenta.
- Strony dotyczące rozliczeń, na których księgowi przeglądają bieżące stany oświadczeń i raporty finansowe.
Każda strona może współdzielić wspólny układ, taki jak menu u góry i szereg często używanych linków u dołu. Jednak strony dotyczące personelu, pacjenta i rozliczeń mogą wymagać dostosowania tego ogólnego układu. Na przykład wszystkie strony specyficzne dla personelu powinny zawierać kalendarz i listę zadań z aktualnie zalogowanym harmonogramem dostępności i harmonogramu dziennego użytkownika. Być może wszystkie strony specyficzne dla pacjenta muszą zawierać informacje o nazwie, adresie i ubezpieczeniu pacjenta, którego informacje są edytowane.
Można tworzyć takie niestandardowe układy przy użyciu zagnieżdżonych stron wzorcowych. Aby zaimplementować powyższy scenariusz, zaczniemy od utworzenia strony wzorcowej, która zdefiniowała układ całej witryny, zawartość menu i stopki z elementami ContentPlaceHolder definiującymi możliwe do dostosowania regiony. Następnie utworzymy trzy zagnieżdżone strony wzorcowe, po jednym dla każdego typu strony internetowej. Każda zagnieżdżona strona wzorcowa definiuje zawartość między typem stron zawartości korzystających ze strony wzorcowej. Innymi słowy, zagnieżdżona strona wzorcowa dla stron zawartości specyficznej dla pacjenta będzie zawierać znaczniki i logikę programową do wyświetlania informacji o edytowanym pacjencie. Tworząc nową stronę specyficzną dla pacjenta, powiązalibyśmy ją z tą zagnieżdżonym stroną wzorcową.
Ten samouczek rozpoczyna się od wyróżniania zalet zagnieżdżonych stron wzorcowych. Następnie przedstawiono sposób tworzenia i używania zagnieżdżonych stron wzorcowych.
Uwaga
Zagnieżdżone strony wzorcowe były możliwe od wersji 2.0 programu .NET Framework. Jednak program Visual Studio 2005 nie uwzględnia obsługi czasu projektowania dla zagnieżdżonych stron wzorcowych. Dobrą wiadomością jest to, że program Visual Studio 2008 oferuje bogate środowisko czasu projektowania dla zagnieżdżonych stron wzorcowych. Jeśli interesuje Cię używanie zagnieżdżonych stron wzorcowych, ale nadal korzystasz z programu Visual Studio 2005, zapoznaj się z wpisem w blogu Scotta Guthrie, Porady dotyczące zagnieżdżonych stron wzorcowych w programie VS 2005 Design-Time.
Zalety zagnieżdżonych stron wzorcowych
Wiele witryn internetowych ma nadrzędny projekt witryny, a także bardziej dostosowane projekty specyficzne dla niektórych typów stron. Na przykład w naszej demonstracyjnej aplikacji internetowej utworzyliśmy podstawową sekcję Administracja (strony w folderze ~/Admin
). Obecnie strony sieci Web w ~/Admin
folderze używają tej samej strony wzorcowej, co te strony, Site.master
które nie są dostępne w sekcji administracyjnej (a mianowicie lub Alternate.master
, w zależności od wyboru użytkownika).
Uwaga
Na razie udaj, że nasza witryna ma tylko jedną stronę wzorcową: Site.master
. W dalszej części tego samouczka zajmiemy się użyciem zagnieżdżonych stron wzorcowych z dwiema (lub więcej) stronami wzorcowymi rozpoczynającymi się od "Używanie zagnieżdżonej strony wzorcowej dla sekcji administracyjnej".
Załóżmy, że poproszono nas o dostosowanie układu stron administracyjnych w celu uwzględnienia dodatkowych informacji lub linków, które w przeciwnym razie nie będą obecne na innych stronach w witrynie. Istnieją cztery techniki implementowania tego wymagania:
- Ręcznie dodaj informacje specyficzne dla administracji i linki do każdej strony zawartości w folderze
~/Admin
. - Zaktualizuj stronę wzorcową
Site.master
, aby zawierała informacje i linki specyficzne dla sekcji Administracja, a następnie dodaj kod do strony wzorcowej, aby pokazać lub ukryć te sekcje na podstawie tego, czy jedna ze stron administracyjnych jest odwiedzana. - Utwórz nową stronę wzorcową specjalnie dla sekcji Administracja, skopiuj znaczniki z
Site.master
, dodaj informacje i linki specyficzne dla sekcji Administracja, a następnie zaktualizuj strony zawartości w~/Admin
folderze, aby użyć tej nowej strony wzorcowej. - Utwórz zagnieżdżona stronę wzorcową, która jest powiązana
Site.master
z stronami zawartości w~/Admin
folderze, użyj nowej zagnieżdżonej strony wzorcowej. Ta zagnieżdżona strona wzorcowa zawiera tylko dodatkowe informacje i linki specyficzne dla stron administracyjnych i nie będzie musiała powtarzać znaczników już zdefiniowanego w plikuSite.master
.
Pierwszą opcją jest najmniej smaczne. Cały punkt korzystania ze stron wzorcowych polega na odejściu od konieczności ręcznego kopiowania i wklejania typowych znaczników do nowych stron ASP.NET. Druga opcja jest akceptowalna, ale sprawia, że aplikacja jest mniej obsługiwana, ponieważ zbiorczo tworzy strony wzorcowe z adiustacjami, które są wyświetlane tylko od czasu do czasu i wymagają od deweloperów edytowania strony wzorcowej, aby pracować nad tym znacznikiem i pamiętać, kiedy dokładnie, niektóre znaczniki są wyświetlane w porównaniu do momentu ukrycia. Takie podejście byłoby mniej opłacalne, ponieważ dostosowania z coraz większej liczby typów stron sieci Web musiały zostać dostosowane przez tę pojedynczą stronę wzorcową.
Trzecia opcja usuwa problemy z bałaganem i złożonością, które pojawił się przy użyciu drugiej opcji. Jednak główną wadą trójki jest to, że wymaga skopiowania i wklejania wspólnego układu z Site.master
do nowej strony wzorcowej specyficznej dla sekcji Administracja. Jeśli później zdecydujemy się zmienić układ całej witryny, musimy pamiętać, aby zmienić go w dwóch miejscach.
Czwarta opcja, zagnieżdżone strony wzorcowe, daje nam najlepsze z drugiej i trzeciej opcji. Informacje o układzie w całym witrynie są przechowywane w jednym pliku — stronie wzorcowej najwyższego poziomu — podczas gdy zawartość specyficzna dla określonych regionów jest rozdzielona na różne pliki.
Ten samouczek rozpoczyna się od zapoznania się z tworzeniem i używaniem prostej zagnieżdżonej strony wzorcowej. Tworzymy zupełnie nową stronę wzorcową najwyższego poziomu, dwie zagnieżdżone strony wzorcowe i dwie strony zawartości. Począwszy od "Używanie zagnieżdżonej strony wzorcowej dla sekcji administracyjnej", przyjrzymy się aktualizowaniu istniejącej architektury strony wzorcowej w celu uwzględnienia użycia zagnieżdżonych stron wzorcowych. W szczególności tworzymy zagnieżdżonych stron wzorcowych i używamy jej do uwzględnienia dodatkowej zawartości niestandardowej dla stron zawartości w folderze ~/Admin
.
Krok 1. Tworzenie prostej strony wzorcowej najwyższego poziomu
Utworzenie zagnieżdżonego wzorca na podstawie jednej z istniejących stron wzorcowych, a następnie zaktualizowanie istniejącej strony zawartości w celu użycia nowej zagnieżdżonej strony wzorcowej zamiast strony wzorcowej najwyższego poziomu wiąże się z pewną złożonością, ponieważ istniejące strony zawartości oczekują już pewnych kontrolek ContentPlaceHolder zdefiniowanych na stronie wzorcowej najwyższego poziomu. W związku z tym zagnieżdżona strona wzorcowa musi również zawierać te same kontrolki ContentPlaceHolder o tych samych nazwach. Ponadto nasza konkretna aplikacja demonstracyjna ma dwie strony wzorcowe (Site.master
i Alternate.master
), które są dynamicznie przypisywane do strony zawartości na podstawie preferencji użytkownika, co dodatkowo zwiększa tę złożoność. W dalszej części tego samouczka przyjrzymy się aktualizowaniu istniejącej aplikacji w celu używania zagnieżdżonych stron wzorcowych, ale najpierw skoncentrujemy się na prostych zagnieżdżonych stronach wzorcowych.
Utwórz nowy folder o nazwie NestedMasterPages
, a następnie dodaj nowy plik strony wzorcowej do tego folderu o nazwie Simple.master
. (Zobacz Rysunek 1, aby zapoznać się ze zrzutem ekranu Eksplorator rozwiązań po dodaniu tego folderu i pliku). Przeciągnij AlternateStyles.css
plik arkusza stylów z Eksplorator rozwiązań na projektanta. Spowoduje to dodanie <link>
elementu do pliku arkusza stylów w elemecie <head>
, po którym znacznik elementu strony <head>
wzorcowej powinien wyglądać następująco:
<head runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<link href="../AlternateStyles.css" rel="stylesheet" type="text/css" />
</head>
Następnie dodaj następujący znacznik w formularzu internetowym elementu Simple.master
:
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server"
NavigateUrl="~/NestedMasterPages/Default.aspx"
Text="Nested Master Pages Tutorial (Simple)" />
</div>
<div id="mainContent">
<asp:ContentPlaceHolder id="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
Ten znacznik wyświetla link zatytułowany "Zagnieżdżone strony wzorcowe (proste)" w górnej części strony w dużej białej czcionki na granatowym tle. Poniżej znajduje się MainContent
element ContentPlaceHolder. Rysunek 1 przedstawia stronę wzorcową Simple.master
po załadowaniu do projektanta programu Visual Studio.
Rysunek 01. Zagnieżdżona strona wzorcowa definiuje zawartość specyficzną dla stron w sekcji Administracja (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2. Tworzenie prostej zagnieżdżonej strony wzorcowej
Simple.master
zawiera dwie kontrolki ContentPlaceHolder: MainContent
Element ContentPlaceHolder dodany w formularzu sieci Web wraz z elementem head
ContentPlaceHolder <head>
. Gdyby utworzyć stronę zawartości i powiązać ją ze Simple.master
stroną zawartości, będą miałyby dwie kontrolki Zawartość odwołujące się do dwóch symboli ContentPlaceHolders. Podobnie, jeśli utworzymy zagnieżdżonych stron wzorcowych i powiązamy ją z Simple.master
nią, zagnieżdżona strona wzorcowa będzie zawierać dwie kontrolki Zawartość.
Dodajmy nową zagnieżdżona stronę wzorcową do NestedMasterPages
folderu o nazwie SimpleNested.master
. Kliknij prawym przyciskiem myszy NestedMasterPages
folder i wybierz polecenie Dodaj nowy element. Spowoduje to wyświetlenie okna dialogowego Dodawanie nowego elementu pokazanego na rysunku 2. Wybierz typ szablonu strony wzorcowej i wpisz nazwę nowej strony wzorcowej. Aby wskazać, że nowa strona wzorcowa powinna być zagnieżdżoną stroną wzorcową, zaznacz pole wyboru "Wybierz stronę wzorcową".
Następnie kliknij przycisk Dodaj. Spowoduje to wyświetlenie tego samego okna dialogowego Wybieranie strony wzorcowej widocznego podczas wiązania strony zawartości ze stroną wzorcową (zobacz Rysunek 3). Wybierz stronę wzorcową Simple.master
w folderze NestedMasterPages
i kliknij przycisk OK.
Uwaga
Jeśli utworzono witrynę internetową ASP.NET przy użyciu modelu projektu aplikacji internetowej zamiast modelu projektu witryny sieci Web, pole wyboru "Wybierz stronę wzorcową" nie będzie widoczne w oknie dialogowym Dodawanie nowego elementu pokazanego na rysunku 2. Aby utworzyć zagnieżdżonych stron wzorcowych podczas korzystania z modelu projektu aplikacji internetowej, należy wybrać szablon zagnieżdżonej strony wzorcowej (zamiast szablonu strony wzorcowej). Po wybraniu szablonu zagnieżdżonej strony wzorcowej i kliknięciu przycisku Dodaj zostanie wyświetlone to samo okno dialogowe Wybieranie strony wzorcowej pokazane na rysunku 3.
Rysunek 02. Zaznacz pole wyboru "Zaznacz stronę wzorcową", aby dodać zagnieżdżoną stronę wzorcową (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 03. Powiązanie zagnieżdżonej strony wzorcowej ze stroną wzorcową Simple.master
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Zagnieżdżone znaczniki deklaratywne strony wzorcowej, pokazane poniżej, zawierają dwie kontrolki Zawartość odwołujące się do dwóch kontrolek ContentPlaceHolder strony wzorcowej najwyższego poziomu.
<%@ Master Language="VB" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNested.master.vb" Inherits="NestedMasterPages_SimpleNested" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
<%@ Master %>
Z wyjątkiem dyrektywy początkowe znaczniki deklaratywne zagnieżdżonej strony wzorcowej są identyczne z adiustacją, która jest początkowo generowana podczas tworzenia powiązania strony zawartości z tą samą stroną wzorcową najwyższego poziomu. Podobnie jak dyrektywa strony <%@ Page %>
zawartości, <%@ Master %>
dyrektywa zawiera tutaj MasterPageFile
atrybut określający zagnieżdżonej strony wzorcowej nadrzędnej strony wzorcowej. Główną różnicą między zagnieżdżonymi stronami wzorcową a stroną zawartości powiązaną z tą samą stroną wzorcową najwyższego poziomu jest to, że zagnieżdżona strona wzorcowa może zawierać kontrolki ContentPlaceHolder. Zagnieżdżone kontrolki ContentPlaceHolder strony wzorcowej definiują regiony, w których strony zawartości mogą dostosowywać znaczniki.
Zaktualizuj tę zagnieżdżoną stronę wzorcową, aby wyświetlała tekst "Hello, from SimpleNested!" w kontrolce Zawartość odpowiadającą MainContent
kontrolce ContentPlaceHolder.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<p>Hello, from SimpleNested!</p>
</asp:Content>
Po dodaniu zapisz zagnieżdżona stronę wzorcową, a następnie dodaj nową stronę zawartości do NestedMasterPages
folderu o nazwie Default.aspx
i powiąż ją ze stroną wzorcową SimpleNested.master
. Po dodaniu tej strony możesz się dziwić, że nie zawiera żadnych kontrolek Zawartości (zobacz Rysunek 4)! Strona zawartości może uzyskiwać dostęp tylko do symboli ContentPlaceHolders nadrzędnej strony wzorcowej. SimpleNested.master
nie zawiera żadnych kontrolek ContentPlaceHolder; w związku z tym żadna strona zawartości powiązana z tą stroną wzorcową nie może zawierać żadnych kontrolek Zawartość.
Rysunek 04. Nowa strona zawartości nie zawiera kontrolek zawartości (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Musimy zaktualizować zagnieżdżonych stron wzorcowych (SimpleNested.master
), aby uwzględnić kontrolki ContentPlaceHolder. Zazwyczaj chcesz, aby zagnieżdżone strony wzorcowe zawierały symbol ContentPlaceHolder dla każdego symbolu ContentPlaceHolder zdefiniowanego przez nadrzędną stronę wzorcową, dzięki czemu jej podrzędna strona wzorcowa lub strona zawartości będą mogły pracować z dowolną kontrolką ContentPlaceHolder strony wzorcowej najwyższego poziomu.
Zaktualizuj stronę wzorcową, SimpleNested.master
aby uwzględnić element ContentPlaceHolder w dwóch kontrolkach Zawartość. Nadaj kontrolkom ContentPlaceHolder taką samą nazwę jak kontrolka ContentPlaceHolder, do których odwołuje się kontrolka ContentPlaceHolder. Oznacza to, że dodaj kontrolkę ContentPlaceHolder o nazwie MainContent
do kontrolki Zawartość w SimpleNested.master
pliku, która odwołuje się MainContent
do elementu ContentPlaceHolder w elemencie Simple.master
. Wykonaj to samo w kontrolce Zawartość, która odwołuje się do elementu head
ContentPlaceHolder.
Uwaga
Chociaż zalecam nazewnictwo kontrolek ContentPlaceHolder na zagnieżdżonej stronie wzorcowej tak samo jak w przypadku symboli ContentPlaceHolder na stronie wzorcowej najwyższego poziomu, ta symetria nazewnictwa nie jest wymagana. Kontrolki ContentPlaceHolder można nadać zagnieżdżonej stronie wzorcowej dowolną nazwę. Jednak łatwiej jest zapamiętać, jakie elementy ContentPlaceHolders odpowiadają regionom strony, jeśli moja strona wzorcowa najwyższego poziomu i zagnieżdżone strony wzorcowe używają tych samych nazw.
Po dodaniu tych dodatków SimpleNested.master
znacznik deklaratywny strony wzorcowej powinien wyglądać podobnie do następującego:
<%@ Master Language="VB" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNested.master.vb" Inherits="NestedMasterPages_SimpleNested" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<p>Hello, from SimpleNested!</p>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Usuń właśnie utworzoną Default.aspx
stronę zawartości, a następnie ponownie ją dodaj, wiążąc ją ze stroną wzorcową SimpleNested.master
. Tym razem program Visual Studio dodaje do elementu Default.aspx
dwie kontrolki Zawartość, odwołując się do symboli ContentPlaceHolder zdefiniowanych w programie SimpleNested.master
(zobacz Rysunek 6). Dodaj tekst "Hello, from Default.aspx!" (Witaj, z Default.aspx!" w kontrolce Zawartość, do którego odwołuje się MainContent
element .
Na rysunku 5 przedstawiono trzy zaangażowane jednostki — Simple.master
, SimpleNested.master
i Default.aspx
— oraz sposób ich powiązania ze sobą. Jak pokazano na diagramie, zagnieżdżona strona wzorcowa implementuje kontrolki Zawartość dla elementu nadrzędnego ContentPlaceHolder. Jeśli te regiony muszą być dostępne dla strony zawartości, zagnieżdżona strona wzorcowa musi dodać własne symbole ContentPlaceHolders do kontrolek Zawartość.
Rysunek 05. Strony wzorcowe najwyższego poziomu i zagnieżdżone określają układ strony zawartości (kliknij, aby wyświetlić obraz pełnowymiarowy)
To zachowanie ilustruje, jak strona zawartości lub strona wzorcowa jest tylko poznawanie nadrzędnej strony wzorcowej. To zachowanie jest również wskazywane przez projektanta programu Visual Studio. Rysunek 6 przedstawia projektanta dla elementu Default.aspx
. Projektant wyraźnie pokazuje, jakie regiony można edytować na stronie zawartości i jakie części nie są, ale nie określa, jakie regiony nie są edytowalne ze strony wzorcowej zagnieżdżonej i jakie regiony znajdują się na stronie wzorcowej najwyższego poziomu.
Rysunek 06. Strona zawartości zawiera teraz kontrolki zawartości dla zagnieżdżonych symboli ContentPlaceHolder strony wzorcowej (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 3. Dodawanie drugiej prostej zagnieżdżonej strony wzorcowej
Korzyść z zagnieżdżonych stron wzorcowych jest bardziej widoczna, gdy istnieje wiele zagnieżdżonych stron wzorcowych. Aby zilustrować tę korzyść, utwórz inną zagnieżdżona stronę wzorcową w NestedMasterPages
folderze; nadaj tej nowej zagnieżdżonej stronie SimpleNestedAlternate.master
wzorcowej nazwę i powiąż ją ze stroną wzorcową Simple.master
. Dodaj kontrolki ContentPlaceHolder w dwóch kontrolkach zawartości zagnieżdżonej strony wzorcowej, tak jak w kroku 2. Dodaj również tekst "Hello, from SimpleNestedAlternate!" w kontrolce Zawartość, która odpowiada symbolowi ContentPlaceHolder strony wzorcowej MainContent
najwyższego poziomu. Po wprowadzeniu tych zmian znacznik deklaratywny nowej zagnieżdżonej strony wzorcowej powinien wyglądać podobnie do następującego:
<%@ Master Language="VB" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNestedAlternate.master.vb" Inherits="NestedMasterPages_SimpleNestedAlternate" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder> </asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<p>Hello, from SimpleNestedAlternate!</p>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Utwórz stronę zawartości o nazwie Alternate.aspx
w folderze NestedMasterPages
i powiąż ją ze zagnieżdżonym stroną wzorcową SimpleNestedAlternate.master
. Dodaj tekst "Hello, from Alternate!" w kontrolce Zawartość, która odpowiada .MainContent
Rysunek 7 przedstawia Alternate.aspx
wyświetlanie w programie Visual Studio Designer.
Rysunek 07. Alternate.aspx
Element jest powiązany ze stroną wzorcową SimpleNestedAlternate.master
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Porównaj projektanta na rysunku 7 z Projektantem na rysunku 6. Obie strony zawartości współużytkują ten sam układ zdefiniowany na stronie wzorcowej najwyższego poziomu (Simple.master
), a mianowicie tytuł "Zagnieżdżone strony wzorcowe (prosty)". Jednak obie mają odrębną zawartość zdefiniowaną na nadrzędnych stronach wzorcowych — tekst "Hello, from SimpleNested!" na rysunku 6 i "Hello, from SimpleNestedAlternate!" na rysunku 7. Niestety, te różnice są proste, ale można rozszerzyć ten przykład, aby uwzględnić bardziej znaczące różnice. Na przykład SimpleNested.master
strona może zawierać menu z opcjami specyficznymi dla jej stron zawartości, natomiast SimpleNestedAlternate.master
może zawierać informacje istotne dla stron zawartości powiązanych z nią.
Teraz wyobraź sobie, że musieliśmy wprowadzić zmianę w nadrzędnym układzie witryny. Załóżmy na przykład, że chcemy dodać listę wspólnych linków do wszystkich stron zawartości. Aby to osiągnąć, zaktualizujemy stronę wzorcową najwyższego poziomu. Simple.master
Wszelkie zmiany są natychmiast odzwierciedlone na zagnieżdżonych stronach wzorcowych i według rozszerzenia ich stron zawartości.
Aby zademonstrować łatwość zmiany nadrzędnego układu witryny, otwórz Simple.master
stronę wzorcową i dodaj następujący znacznik między elementami topContent
i mainContent
<div>
:
<div id="navContent">
<asp:HyperLink ID="lnkDefault" runat="server"
NavigateUrl="~/NestedMasterPages/Default.aspx"
Text="Nested Master Page Example 1" />
|
<asp:HyperLink ID="lnkAlternate" runat="server"
NavigateUrl="~/NestedMasterPages/Alternate.aspx"
Text="Nested Master Page Example 2" />
</div>
Spowoduje to dodanie dwóch linków do góry każdej strony powiązanej z Simple.master
elementem , SimpleNested.master
lub SimpleNestedAlternate.master
; te zmiany dotyczą wszystkich zagnieżdżonych stron wzorcowych i ich stron zawartości natychmiast. Rysunek 8 przedstawia Alternate.aspx
wyświetlanie w przeglądarce. Zwróć uwagę na dodanie linków w górnej części strony (w porównaniu do rysunku 7).
Rysunek 08. Zmiana na stronę wzorcową najwyższego poziomu jest natychmiast odzwierciedlana na zagnieżdżonych stronach wzorcowych i ich stronach zawartości (kliknij, aby wyświetlić obraz pełnowymiarowy)
Używanie zagnieżdżonej strony wzorcowej dla sekcji Administracja
W tym momencie przyjrzeliśmy się zaletom zagnieżdżonych stron wzorcowych i pokazano, jak tworzyć i używać ich w aplikacji ASP.NET. Przykłady opisane w krokach 1, 2 i 3 obejmowały jednak utworzenie nowej strony wzorcowej najwyższego poziomu, nowych zagnieżdżonych stron wzorcowych i nowych stron zawartości. Co z dodawaniem nowej zagnieżdżonej strony wzorcowej do witryny internetowej z istniejącą stroną wzorcową najwyższego poziomu i stronami zawartości?
Zintegrowanie zagnieżdżonej strony wzorcowej z istniejącą witryną internetową i skojarzenie jej z istniejącymi stronami zawartości wymaga nieco więcej wysiłku niż rozpoczęcie od podstaw. Kroki 4, 5, 6 i 7 badają te wyzwania, ponieważ rozszerzamy naszą aplikację demonstracyjną o nową zagnieżdżona stronę wzorcową o nazwie AdminNested.master
zawierającą instrukcje administratora i są używane przez strony ASP.NET w folderze ~/Admin
.
Zintegrowanie zagnieżdżonej strony wzorcowej z naszą aplikacją demonstracyjną wprowadza następujące przeszkody:
- Istniejące strony zawartości w folderze
~/Admin
mają pewne oczekiwania od strony wzorcowej. Na początek oczekują, że niektóre kontrolki ContentPlaceHolder będą obecne. Ponadto~/Admin/AddProduct.aspx
strony i~/Admin/Products.aspx
nazywają publiczną metodę strony wzorcowejRefreshRecentProductsGrid
, ustawiają jejGridMessageText
właściwość lub mają program obsługi zdarzeń dla jegoPricesDoubled
zdarzenia. W związku z tym nasza zagnieżdżona strona wzorcowa musi zawierać te same elementy contentPlaceHolders i publiczne elementy członkowskie. - W poprzednim samouczku ulepszyliśmy klasę
BasePage
tak, aby dynamicznie ustawiałaPage
właściwość obiektuMasterPageFile
na podstawie zmiennej Sesja. Jak obsługiwać dynamiczne strony wzorcowe podczas korzystania z zagnieżdżonych stron wzorcowych?
Te dwa wyzwania będą wyświetlane podczas tworzenia zagnieżdżonej strony wzorcowej i używania jej z istniejących stron zawartości. Zbadamy i odinstalujemy te problemy w miarę ich powstawania.
Krok 4. Tworzenie zagnieżdżonej strony wzorcowej
Pierwszym zadaniem jest utworzenie zagnieżdżonej strony wzorcowej, która będzie używana przez strony w sekcji Administracja. Jak pokazano w kroku 2, podczas dodawania nowej zagnieżdżonej strony wzorcowej musimy określić nadrzędną stronę wzorcową zagnieżdżonej strony wzorcowej. Mamy jednak dwie strony wzorcowe najwyższego poziomu: Site.master
i Alternate.master
. Pamiętaj, że utworzyliśmy Alternate.master
w poprzednim samouczku i napisaliśmy kod w BasePage
klasie, która ustawiła Page
właściwość obiektu MasterPageFile
w czasie wykonywania na Site.master
wartość lub Alternate.master
w zależności od wartości MyMasterPage
zmiennej Sesja.
Jak skonfigurować naszą zagnieżdżona stronę wzorcową tak, aby korzystała z odpowiedniej strony wzorcowej najwyższego poziomu? Mamy dwie opcje:
- Utwórz dwie zagnieżdżone strony
AdminNestedSite.master
wzorcowe iAdminNestedAlternate.master
, i powiąż je odpowiednio ze stronamiSite.master
wzorcowym najwyższego poziomu iAlternate.master
. WBasePage
pliku ustawilibyśmyPage
obiektMasterPageFile
na odpowiednią zagnieżdżonej stronie wzorcowej. - Utwórz pojedynczą zagnieżdżona stronę wzorcową i użyj tej konkretnej strony wzorcowej. Następnie w czasie wykonywania musimy ustawić właściwość zagnieżdżonej strony
MasterPageFile
wzorcowej na odpowiednią stronę wzorcową najwyższego poziomu w czasie wykonywania. (Jak można było dowiedzieć się teraz, strony wzorcowe również mająMasterPageFile
właściwość.
Użyjmy drugiej opcji. Utwórz pojedynczy zagnieżdżony plik strony wzorcowej ~/Admin
w folderze o nazwie AdminNested.master
. Ponieważ zarówno Site.master
, jak i Alternate.master
mają ten sam zestaw kontrolek ContentPlaceHolder, nie ma znaczenia, z jaką stroną wzorcową wiążesz ją, chociaż zachęcam do powiązania jej Site.master
ze względami spójności.
Rysunek 09. Dodawanie zagnieżdżonej strony wzorcowej ~/Admin
do folderu. (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Ponieważ zagnieżdżona strona wzorcowa jest powiązana ze stroną wzorcową z czterema kontrolkami ContentPlaceHolder, program Visual Studio dodaje cztery kontrolki Zawartość do nowego zagnieżdżonego pliku strony wzorcowej początkowego znaczników. Podobnie jak w krokach 2 i 3, dodaj kontrolkę ContentPlaceHolder w każdej kontrolce Zawartość, nadając jej taką samą nazwę jak kontrolka ContentPlaceHolder strony wzorcowej najwyższego poziomu. Dodaj również następujący znacznik do kontrolki Zawartość odpowiadającą symbolowi MainContent
ContentPlaceHolder:
<div class="instructions">
<b>Administration Instructions:</b>
<br />
The pages in the Administration section allow you, the Administrator, to
add new products and view existing products.
</div>
Następnie zdefiniuj klasę instructions
CSS w plikach Styles.css
i AlternateStyles.css
CSS. Następujące reguły CSS powodują, że elementy HTML stylizowane z klasą mają być wyświetlane z instructions
jasnożółtym kolorem tła i czarnym, stałym obramowaniem:
.instructions
{
padding: 6px;
border: dashed 1px black;
background-color: #ffb;
margin-bottom: 10px;
}
Ponieważ ten znacznik został dodany do zagnieżdżonej strony wzorcowej, będzie on wyświetlany tylko na tych stronach, które używają tej zagnieżdżonej strony wzorcowej (czyli stron w sekcji Administracja).
Po dodaniu tych dodatków do zagnieżdżonej strony wzorcowej jej deklaratywne znaczniki powinny wyglądać podobnie do następujących:
<%@ Master Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="AdminNested.master.vb" Inherits="Admin_AdminNested" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<div class="instructions">
<b>Administration Instructions:</b>
<br />
The pages in the Administration section allow you, the Administrator, to
add new products and view existing products.
</div>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="QuickLoginUI" Runat="Server">
<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="LeftColumnContent" Runat="Server">
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Należy pamiętać, że każda kontrolka Zawartość ma kontrolkę ContentPlaceHolder i że właściwości kontrolki ID
ContentPlaceHolder są przypisane do tych samych wartości co odpowiednie kontrolki ContentPlaceHolder na stronie wzorcowej najwyższego poziomu. Ponadto znaczniki specyficzne dla sekcji Administracja są wyświetlane w symbolu MainContent
ContentPlaceHolder.
Rysunek 10 przedstawia AdminNested.master
zagnieżdżonych stron wzorcowych podczas przeglądania za pomocą projektanta programu Visual Studio. Instrukcje są widoczne w żółtym polu w górnej części kontrolki MainContent
Zawartość.
Rysunek 10. Zagnieżdżona strona wzorcowa rozszerza stronę wzorcową najwyższego poziomu w celu uwzględnienia instrukcji dla administratora. (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 5. Aktualizowanie istniejących stron zawartości w celu używania nowej zagnieżdżonej strony wzorcowej
Za każdym razem, gdy dodamy nową stronę zawartości do sekcji Administracja, musimy powiązać ją ze właśnie utworzoną stroną wzorcową AdminNested.master
. Ale co z istniejącymi stronami zawartości? Obecnie wszystkie strony zawartości w witrynie pochodzą z BasePage
klasy , która programowo ustawia stronę wzorcową strony zawartości w czasie wykonywania. Nie jest to zachowanie, które chcemy uzyskać dla stron zawartości w sekcji Administracja. Zamiast tego chcemy, aby te strony zawartości zawsze używały AdminNested.master
strony. Obowiązkiem zagnieżdżonej strony wzorcowej będzie wybranie odpowiedniej strony zawartości najwyższego poziomu w czasie wykonywania.
Najlepszym sposobem osiągnięcia tego żądanego zachowania jest utworzenie nowej niestandardowej klasy strony bazowej o nazwie AdminBasePage
, która rozszerza klasę BasePage
. AdminBasePage
Następnie można zastąpić SetMasterPageFile
i ustawić Page
obiekt MasterPageFile
na wartość "~/Admin/AdminNested.master". W ten sposób każda strona pochodząca z AdminBasePage
metody będzie używać AdminNested.master
metody , natomiast każda strona pochodząca z BasePage
tej metody będzie miała właściwość MasterPageFile
ustawioną dynamicznie na wartość "~/Site.master" lub "~/Alternate.master" na podstawie wartości MyMasterPage
zmiennej Sesja.
Zacznij od dodania nowego pliku klasy do App_Code
folderu o nazwie AdminBasePage.vb
. Przesłoń AdminBasePage
metodę , a następnie ją przesłonięć BasePage
SetMasterPageFile
. W tej metodzie przypisz MasterPageFile
wartość "~/Admin/AdminNested.master". Po wprowadzeniu tych zmian plik klasy powinien wyglądać podobnie do następującego:
Public Class AdminBasePage
Inherits BasePage
Protected Overrides Sub SetMasterPageFile()
Me.MasterPageFile = "~/Admin/AdminNested.master"
End Sub
End Class
Teraz musimy mieć istniejące strony zawartości w sekcji Administracja pochodzą z AdminBasePage
zamiast BasePage
. Przejdź do pliku klasy za kodem dla każdej strony zawartości w folderze ~/Admin
i wprowadź tę zmianę. Na przykład w pliku ~/Admin/Default.aspx
należy zmienić deklarację klasy za kodem z:
Partial Class Admin_Default
Inherits BasePage
Do:
Partial Class Admin_Default
Inherits AdminBasePage
Rysunek 11 przedstawia sposób, w jaki strona wzorcowa najwyższego poziomu (Site.master
lub Alternate.master
), zagnieżdżona strona wzorcowa (AdminNested.master
) i strony zawartości sekcji Administracja odnoszą się do siebie nawzajem.
Rysunek 11. Zagnieżdżona strona wzorcowa definiuje zawartość specyficzną dla stron w sekcji Administracja (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 6. Dublowanie publicznych metod i właściwości strony wzorcowej
Pamiętaj, że ~/Admin/AddProduct.aspx
strony i ~/Admin/Products.aspx
współdziałają programowo ze stroną wzorcową: ~/Admin/AddProduct.aspx
wywołuje publiczną metodę strony RefreshRecentProductsGrid
wzorcowej i ustawia jej GridMessageText
właściwość; ~/Admin/Products.aspx
ma program obsługi zdarzeń dla PricesDoubled
zdarzenia. W poprzednim samouczku utworzyliśmy klasę MustInherit
BaseMasterPage
, która zdefiniowała te publiczne elementy członkowskie.
Strony ~/Admin/AddProduct.aspx
i ~/Admin/Products.aspx
zakładają, że ich strona wzorcowa BaseMasterPage
pochodzi z klasy . Jednak AdminNested.master
strona obecnie rozszerza klasę System.Web.UI.MasterPage
. W związku z tym podczas odwiedzania ~/Admin/Products.aspx
obiektu InvalidCastException
jest zgłaszany komunikat: "Nie można rzutować obiektu typu "ASP.admin_adminnested_master", aby wpisać "BaseMasterPage".
Aby rozwiązać ten problem, musimy rozszerzyć BaseMasterPage
klasę AdminNested.master
za kodem. Zaktualizuj deklarację klasy zagnieżdżonej strony wzorcowej z:
Partial Class Admin_AdminNested
Inherits System.Web.UI.MasterPage
Do:
Partial Class Admin_AdminNested
Inherits BaseMasterPage
Jeszcze nie zrobiliśmy. Musimy zastąpić elementy członkowskie oznaczone jako MustOverride
, a mianowicie RefreshRecentProductsGrid
i GridMessageText
. Te elementy członkowskie są używane przez strony wzorcowe najwyższego poziomu do aktualizowania interfejsów użytkownika. (W rzeczywistości tylko strona wzorcowa Site.master
używa tych metod, chociaż obie strony wzorcowe najwyższego poziomu implementują te metody, ponieważ oba te metody są rozszerzane BaseMasterPage
).
Chociaż musimy zaimplementować te elementy członkowskie w AdminNested.master
programie , wszystkie te implementacje muszą być po prostu wywoływane przez ten sam element członkowski na stronie wzorcowej najwyższego poziomu używanej przez zagnieżdżonej stronie wzorcowej. Na przykład gdy strona zawartości w sekcji Administracja wywołuje metodę zagnieżdżonej strony RefreshRecentProductsGrid
wzorcowej, wszystkie zagnieżdżone strony wzorcowej muszą wykonać z kolei wywołanie Site.master
metody lub Alternate.master
metody RefreshRecentProductsGrid
.
Aby to osiągnąć, zacznij od dodania następującej @MasterType
dyrektywy na początku elementu AdminNested.master
:
<%@ MasterType TypeName="BaseMasterPage" %>
Pamiętaj, że @MasterType
dyrektywa dodaje silnie typizowana właściwość do klasy code-behind o nazwie Master
. Następnie przesłoń RefreshRecentProductsGrid
elementy członkowskie i GridMessageText
i po prostu deleguj wywołanie do Master
odpowiedniej metody :
Partial Class Admin_AdminNested
Inherits BaseMasterPage
Public Overrides Property GridMessageText() As String
Get
Return Master.GridMessageText
End Get
Set(ByVal value As String)
Master.GridMessageText = value
End Set
End Property
Public Overrides Sub RefreshRecentProductsGrid()
Master.RefreshRecentProductsGrid()
End Sub
End Class
Po zainstalowaniu tego kodu powinno być możliwe odwiedzanie stron zawartości i korzystanie z nich w sekcji Administracja. Rysunek 12 przedstawia ~/Admin/Products.aspx
stronę po wyświetleniu za pośrednictwem przeglądarki. Jak widać, strona zawiera pole Instrukcje administracyjne zdefiniowane na zagnieżdżonej stronie wzorcowej.
Rysunek 12. Strony zawartości w sekcji Administracja zawierają instrukcje w górnej części każdej strony (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 7. Używanie odpowiedniej strony wzorcowej najwyższego poziomu w środowisku uruchomieniowym
Chociaż wszystkie strony zawartości w sekcji Administracja są w pełni funkcjonalne, wszystkie używają tej samej strony wzorcowej najwyższego poziomu i ignorują stronę wzorcową wybraną przez użytkownika na stronie ChooseMasterPage.aspx
. Takie zachowanie wynika z faktu, że zagnieżdżona strona wzorcowa ma MasterPageFile
statycznie ustawioną właściwość na Site.master
wartość w swojej <%@ Master %>
dyrektywie.
Aby użyć strony wzorcowej najwyższego poziomu wybranej przez użytkownika końcowego, musimy ustawić AdminNested.master
właściwość "s MasterPageFile
" na wartość w zmiennej MyMasterPage
Sesja. Ponieważ ustawiamy właściwości stron MasterPageFile
zawartości w BasePage
pliku , można pomyśleć, że ustawimy właściwość zagnieżdżonej strony MasterPageFile
wzorcowej w BaseMasterPage
klasie lub w AdminNested.master
klasie "code-behind". Nie będzie to jednak działać, ponieważ musimy ustawić MasterPageFile
właściwość na końcu etapu PreInit. Najwcześniejszy czas, w którym można programowo wykorzystać cykl życia strony ze strony wzorcowej, to etap Init (który występuje po etapie PreInit).
W związku z tym musimy ustawić właściwość zagnieżdżonej strony MasterPageFile
wzorcowej ze stron zawartości. Jedyne strony zawartości korzystające ze strony wzorcowej AdminNested.master
pochodzą z elementu AdminBasePage
. W związku z tym możemy tam umieścić tę logikę. W kroku 5 zastąpimy metodę SetMasterPageFile
, ustawiając właściwość obiektu MasterPageFile
Page na "~/Admin/AdminNested.master". Zaktualizuj SetMasterPageFile
właściwość , aby ustawić właściwość strony wzorcowej MasterPageFile
na wynik przechowywany w sesji:
Public Class AdminBasePage
Inherits BasePage
Protected Overrides Sub SetMasterPageFile()
Me.MasterPageFile = "~/Admin/AdminNested.master"
Page.Master.MasterPageFile = MyBase.GetMasterPageFileFromSession()
End Sub
End Class
Metoda GetMasterPageFileFromSession
, którą dodaliśmy do BasePage
klasy w poprzednim samouczku, zwraca odpowiednią ścieżkę pliku strony wzorcowej na podstawie wartości zmiennej sesji.
Dzięki tej zmianie wybór strony wzorcowej użytkownika jest przenoszone do sekcji Administracja. Rysunek 13 przedstawia tę samą stronę co Rysunek 12, ale po zmianie wyboru Alternate.master
strony wzorcowej na .
Rysunek 13. Strona administracji zagnieżdżonej używa strony wzorcowej najwyższego poziomu wybranej przez użytkownika (kliknij, aby wyświetlić obraz pełnowymiarowy)
Podsumowanie
Podobnie jak sposób powiązania stron zawartości ze stroną wzorcową, można utworzyć zagnieżdżone strony wzorcowe przez powiązanie podrzędnej strony wzorcowej ze stroną wzorcową nadrzędną. Podrzędna strona wzorcowa może definiować kontrolki Zawartość dla każdego elementu nadrzędnego ContentPlaceHolders; Następnie może dodać własne kontrolki ContentPlaceHolder (a także inne znaczniki) do tych kontrolek Zawartości. Zagnieżdżone strony wzorcowe są bardzo przydatne w dużych aplikacjach internetowych, w których wszystkie strony współużytkują nadrzędny wygląd i działanie, ale niektóre sekcje witryny wymagają unikatowych dostosowań.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Zagnieżdżone strony wzorcowe ASP.NET
- Porady dotyczące zagnieżdżonych stron wzorcowych i czasu projektowania programu VS 2005
- Obsługa zagnieżdżonych stron wzorcowych programu VS 2008
Informacje o autorze
Scott Mitchell, autor wielu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 3,5 w ciągu 24 godzin. Scott można uzyskać na mitchell@4GuysFromRolla.com stronie lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com