Udostępnij za pośrednictwem


Zagnieżdżone strony wzorcowe (C#)

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:

  1. Ręcznie dodaj informacje specyficzne dla administracji i linki do każdej strony zawartości w folderze ~/Admin .
  2. 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.
  3. 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.
  4. 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 pliku Site.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.

Strona wzorcowa Simple dot 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.

Zaznacz pole wyboru

Rysunek 02. Zaznacz pole wyboru "Zaznacz stronę wzorcową", aby dodać zagnieżdżoną stronę wzorcową (kliknij, aby wyświetlić obraz pełnowymiarowy)

Wiązanie zagnieżdżonej strony wzorcowej ze stroną wzorcową Simple.master

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="C#" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNested.master.cs" 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.aspxi 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ść.

Nowa strona zawartości nie zawiera żadnych kontrolek zawartości

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="C#" MasterPageFile="~/NestedMasterPages/Simple.master"AutoEventWireup="false" CodeFile="SimpleNested.master.cs" 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.aspxdwie 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ę MainContentelement .

Na rysunku 5 przedstawiono trzy zaangażowane jednostki — Simple.master, SimpleNested.masteri 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ść.

Strony wzorcowe najwyższego poziomu i zagnieżdżone określają układ strony zawartości

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.

Strona zawartości zawiera teraz kontrolki zawartości dla zagnieżdżonych symboli zawartości strony wzorcowej

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="C#" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNestedAlternate.master.cs" 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.

Alternate.aspx jest powiązana ze stroną wzorcową SimpleNestedAlternate.master

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.masterelementem , SimpleNested.masterlub 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).

Zmieniono stronę wzorcową najwyższego poziomu natychmiast odzwierciedlone na zagnieżdżonych stronach wzorcowych i ich stronach zawartości

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 wzorcowej RefreshRecentProductsGrid , ustawiają jej GridMessageText właściwość lub mają program obsługi zdarzeń dla jego PricesDoubled 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ła Page właściwość obiektu MasterPageFile 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 właściwość obiektu MasterPageFile Page 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 i AdminNestedAlternate.master, i powiąż je odpowiednio ze stronami Site.master wzorcowym najwyższego poziomu i Alternate.master. W BasePagepliku ustawilibyśmy Page obiekt MasterPageFile 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.

Dodaj zagnieżdżona stronę wzorcową do folderu ~/Admin.

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="C#" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="AdminNested.master.cs" 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ść.

Zagnieżdżona strona wzorcowa rozszerza stronę wzorcową najwyższego poziomu w celu uwzględnienia instrukcji dla administratora.

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.mastermetody , 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.cs. 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 : BasePage 
{ 
    protected override void SetMasterPageFile() 
    { 
        this.MasterPageFile = "~/Admin/AdminNested.master"; 
    } 
}

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:

public partial class Admin_Default : BasePage

Do:

public partial class Admin_Default : 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.

Zagnieżdżona strona wzorcowa definiuje zawartość specyficzną dla stron w sekcji Administracja

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 abstrakcyjną BaseMasterPage klasę, 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ć BaseMasterPageklasę AdminNested.master za kodem. Zaktualizuj deklarację klasy zagnieżdżonej strony wzorcowej z:

public partial class Admin_AdminNested : System.Web.UI.MasterPage

Do:

public partial class Admin_AdminNested : BaseMasterPage

Jeszcze nie zrobiliśmy. BaseMasterPage Ponieważ klasa jest abstrakcyjna, musimy zastąpić abstract elementy członkowskie 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.masterprogramie , 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.mastermetody 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 Masterodpowiedniej metody :

public partial class Admin_AdminNested : BaseMasterPage 
{ 
    public override void RefreshRecentProductsGrid() 
    { 
        Master.RefreshRecentProductsGrid();
    } 
    public override string GridMessageText
    { 
        get 
        {
            return Master.GridMessageText;
        } 
        set
        { 
            Master.GridMessageText = value; 
        } 
    }
}

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.

Strony zawartości w sekcji Administracja zawierają instrukcje w górnej części każdej strony

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.masterwłaściwość "s MasterPageFile " na wartość w zmiennej MyMasterPage Sesja. Ponieważ ustawiamy właściwości stron MasterPageFile zawartości w BasePagepliku , można pomyśleć, że ustawimy właściwość zagnieżdżonej strony MasterPageFile wzorcowej w BaseMasterPage klasie lub w AdminNested.masterklasie "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 Page właściwość obiektu MasterPageFile 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 : BasePage 
{ 
    protected override void SetMasterPageFile() 
    { 
        this.MasterPageFile = "~/Admin/AdminNested.master"; 
        Page.Master.MasterPageFile = base.GetMasterPageFileFromSession(); 
    } 
}

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.masterstrony wzorcowej na .

Strona administracji zagnieżdżonej używa strony wzorcowej najwyższego poziomu wybranej przez użytkownika

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:

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