Programowe określanie strony wzorcowej (VB)
Autor : Scott Mitchell
Przyjrzyj się programowemu ustawianiu strony wzorcowej strony zawartości za pośrednictwem programu obsługi zdarzeń PreInit.
Wprowadzenie
Ponieważ inauguracyjny przykład w artykule Tworzenie układu Site-Wide przy użyciu stron wzorcowych, wszystkie strony zawartości odwoływali się deklaratywnie do strony wzorcowej za pośrednictwem atrybutu MasterPageFile
@Page
w dyrektywie. Na przykład następująca @Page
dyrektywa łączy stronę zawartości ze stroną Site.master
wzorcową :
<%@ Page Language="C#" MasterPageFile="~/Site.master"... %>
KlasaPage
w System.Web.UI
przestrzeni nazw zawiera MasterPageFile
właściwość, która zwraca ścieżkę do strony wzorcowej strony zawartości. Jest to ta właściwość, która jest ustawiana przez dyrektywę@Page
. Tej właściwości można również użyć do programowego określenia strony wzorcowej strony zawartości. Takie podejście jest przydatne, jeśli chcesz dynamicznie przypisać stronę wzorcową na podstawie czynników zewnętrznych, takich jak użytkownik odwiedzający stronę.
W tym samouczku dodajemy drugą stronę wzorcową do naszej witryny internetowej i dynamicznie decydujemy, która strona wzorcowa ma być używana w czasie wykonywania.
Krok 1. Spojrzenie na cykl życia strony
Za każdym razem, gdy żądanie dotrze do serwera internetowego dla strony ASP.NET będącej stroną zawartości, aparat ASP.NET musi połączyć kontrolki Zawartość strony z odpowiednimi kontrolkami ContentPlaceHolder strony wzorcowej. To połączenie tworzy jedną hierarchię sterowania, która może następnie przejść przez typowy cykl życia strony.
Rysunek 1 ilustruje to połączenie. Krok 1 na rysunku 1 przedstawia początkową zawartość i hierarchie kontrolek strony wzorcowej. Na końcu etapu PreInit kontrolki Zawartość na stronie są dodawane do odpowiednich symboli ContentPlaceHolder na stronie wzorcowej (Krok 2). Po tym połączeniu strona wzorcowa służy jako katalog główny hierarchii kontroli połączonej. Ta połączona hierarchia sterowania jest następnie dodawana do strony w celu utworzenia finalizowanej hierarchii sterowania (krok 3). Wynikiem netto jest to, że hierarchia sterowania strony zawiera bezpieczną hierarchię sterowania.
Rysunek 01. Hierarchie kontroli strony wzorcowej i strony zawartości są połączone razem podczas etapu preInit (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2. UstawianieMasterPageFile
właściwości z poziomu kodu
To, co partykuje strona wzorcowa MasterPageFile
w tym połączeniu, zależy od wartości Page
właściwości obiektu. Ustawienie atrybutu MasterPageFile
@Page
w dyrektywie ma wpływ netto na przypisanie Page
właściwości "w MasterPageFile
etapie inicjowania, który jest pierwszym etapem cyklu życia strony. Tę właściwość można też ustawić programowo. Jednak przed wykonaniem łączenia na rysunku 1 należy ustawić tę właściwość.
Na początku etapu Page
PreInit obiekt zgłasza zdarzeniePreInit
i wywołuje jego OnPreInit
metodę. Aby ustawić stronę wzorcową programowo, możemy utworzyć program obsługi zdarzeń dla PreInit
zdarzenia lub zastąpić metodę OnPreInit
. Przyjrzyjmy się obu podejść.
Zacznij od otwarcia Default.aspx.vb
pliku klasy kodu dla strony głównej naszej witryny. Dodaj procedurę obsługi zdarzeń dla zdarzenia strony PreInit
, wpisując następujący kod:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
End Sub
W tym miejscu możemy ustawić MasterPageFile
właściwość . Zaktualizuj kod, aby przypisywać wartość "~/Site.master" do MasterPageFile
właściwości .
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.MasterPageFile = "~/Site.master"
End Sub
Jeśli ustawisz punkt przerwania i zaczniesz od debugowania, zobaczysz, że za każdym razem Default.aspx
, gdy strona zostanie odwiedzona lub gdy nastąpi powrót do tej strony, Page_PreInit
procedura obsługi zdarzeń zostanie wykonana i MasterPageFile
właściwość zostanie przypisana do "~/Site.master".
Alternatywnie można zastąpić metodę Page
klasy OnPreInit
i ustawić MasterPageFile
w niej właściwość . W tym przykładzie nie ustawimy strony wzorcowej w określonej stronie, ale raczej z .BasePage
Pamiętaj, że utworzyliśmy niestandardową klasę strony bazowej (BasePage
) z powrotem w samouczku Określanie tytułu, tagów meta i innych nagłówków HTML na stronie wzorcowej . Obecnie BasePage
zastępuje Page
metodę klasy OnLoadComplete
, w której ustawia właściwość strony Title
na podstawie danych mapy witryny. Zaktualizujmy BasePage
również metodę , aby zastąpić metodę OnPreInit
programowo określającą stronę wzorcową.
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
Me.MasterPageFile = "~/Site.master"
MyBase.OnPreInit(e)
End Sub
Ponieważ wszystkie nasze strony zawartości pochodzą z BasePage
programu , wszystkie z nich mają teraz przypisaną programowo stronę wzorcową. W tym momencie PreInit
program obsługi zdarzeń w Default.aspx.vb
programie jest zbędny; możesz go usunąć.
Co z dyrektywą@Page
?
Co może być nieco mylące jest to, że właściwości stron MasterPageFile
zawartości są teraz określane w dwóch miejscach: programowo w BasePage
metodzie klasy OnPreInit
, a także za pomocą atrybutu MasterPageFile
w dyrektywie każdej strony @Page
zawartości.
Pierwszym etapem cyklu życia strony jest etap inicjowania. Podczas tego etapu Page
właściwość obiektu MasterPageFile
jest przypisywana wartość atrybutu MasterPageFile
w @Page
dyrektywie (jeśli jest podana). Etap PreInit jest zgodny z etapem Inicjowanie i tutaj programowo ustawiamy Page
właściwość obiektu MasterPageFile
, zastępując w ten sposób wartość przypisaną z @Page
dyrektywy . Ponieważ ustawiamy Page
właściwość obiektu MasterPageFile
programowo, możemy usunąć MasterPageFile
atrybut z @Page
dyrektywy bez wpływu na środowisko użytkownika końcowego. Aby przekonać się o tym, przejdź do przodu i usuń MasterPageFile
atrybut z @Page
dyrektywy w Default.aspx
, a następnie odwiedź stronę za pośrednictwem przeglądarki. Jak można oczekiwać, dane wyjściowe są takie same jak przed usunięciem atrybutu.
Określa, MasterPageFile
czy właściwość jest ustawiana za pomocą @Page
dyrektywy, czy programowo, jest niekonsekwencyjna dla środowiska użytkownika końcowego. MasterPageFile
Jednak atrybut w @Page
dyrektywie jest używany przez program Visual Studio w czasie projektowania do tworzenia widoku WYSIWYG w Projektant. Jeśli wrócisz do Default.aspx
programu Visual Studio i przejdziesz do Projektant zostanie wyświetlony komunikat "Błąd strony wzorcowej: Strona zawiera kontrolki wymagające odwołania do strony wzorcowej, ale nie jest określona" (zobacz Rysunek 2).
Krótko mówiąc, należy pozostawić MasterPageFile
atrybut w @Page
dyrektywie, aby cieszyć się zaawansowanym doświadczeniem w czasie projektowania w programie Visual Studio.
@Page do renderowania widoku projektu " />
Rysunek 02. Program Visual Studio używa @Page
atrybutu dyrektywy do renderowania MasterPageFile
widoku projektu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 3. Tworzenie alternatywnej strony wzorcowej
Ponieważ strona wzorcowa strony zawartości może być ustawiana programowo w czasie wykonywania, można dynamicznie załadować określoną stronę wzorcową na podstawie niektórych kryteriów zewnętrznych. Ta funkcja może być przydatna w sytuacjach, w których układ witryny musi się różnić w zależności od użytkownika. Na przykład aplikacja internetowa aparatu blogu może zezwolić swoim użytkownikom na wybór układu dla swojego bloga, w którym każdy układ jest skojarzony z inną stroną wzorcową. W czasie wykonywania, gdy gość wyświetla blog użytkownika, aplikacja internetowa musi określić układ blogu i dynamicznie skojarzyć odpowiednią stronę wzorcową ze stroną zawartości.
Sprawdźmy, jak dynamicznie załadować stronę wzorcową w czasie wykonywania na podstawie niektórych kryteriów zewnętrznych. Nasza witryna internetowa zawiera obecnie tylko jedną stronę wzorcową (Site.master
). Potrzebujemy innej strony wzorcowej, aby zilustrować wybór strony wzorcowej w czasie wykonywania. Ten krok koncentruje się na tworzeniu i konfigurowaniu nowej strony wzorcowej. Krok 4 obejmuje określenie, która strona wzorcowa ma być używana w czasie wykonywania.
Utwórz nową stronę wzorcową w folderze głównym o nazwie Alternate.master
. Dodaj również nowy arkusz stylów do witryny internetowej o nazwie AlternateStyles.css
.
Rysunek 03. Dodawanie kolejnej strony wzorcowej i pliku CSS do witryny sieci Web (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Zaprojektowałem stronę wzorcową Alternate.master
, aby tytuł wyświetlany w górnej części strony, wyśrodkowany i na granatowym tle. Zostałem zwolniony z lewej kolumny i przeniesiono zawartość poniżej MainContent
kontrolki ContentPlaceHolder, która teraz obejmuje całą szerokość strony. Co więcej, mam nixed nieurządkowaną listę lekcji i zastąpiłem ją poziomą listą powyżej MainContent
. Zaktualizowałem również czcionki i kolory używane przez stronę wzorcową (i, według rozszerzenia, jej strony zawartości). Rysunek 4 przedstawia Default.aspx
użycie strony wzorcowej Alternate.master
.
Uwaga
ASP.NET obejmuje możliwość definiowania motywów. Motyw to kolekcja obrazów, plików CSS i ustawień właściwości kontrolki sieci Web związanych ze stylem, które można zastosować do strony w czasie wykonywania. Motywy są sposobem, aby przejść, jeśli układy witryny różnią się tylko wyświetlanymi obrazami i regułami CSS. Jeśli układy różnią się znacznie bardziej, na przykład przy użyciu różnych kontrolek sieci Web lub mają radykalnie inny układ, należy użyć oddzielnych stron wzorcowych. Aby uzyskać więcej informacji na temat motywów, zapoznaj się z sekcją Dalsze informacje na końcu tego samouczka.
Rysunek 04. Nasze strony zawartości mogą teraz używać nowego wyglądu i działania (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Gdy znaczniki stron wzorcowych i zawartości są połączone, klasa sprawdza, MasterPage
czy każda kontrolka Zawartość na stronie zawartości odwołuje się do elementu ContentPlaceHolder na stronie wzorcowej. Wyjątek jest zgłaszany, jeśli zostanie znaleziona kontrolka Content odwołująca się do nieistniejącego symbolu ContentPlaceHolder. Innymi słowy, konieczne jest, aby strona wzorcowa przypisana do strony zawartości miała właściwość ContentPlaceHolder dla każdej kontrolki Zawartość na stronie zawartości.
Strona wzorcowa Site.master
zawiera cztery kontrolki ContentPlaceHolder:
head
MainContent
QuickLoginUI
LeftColumnContent
Niektóre strony zawartości w naszej witrynie internetowej zawierają tylko jedną lub dwie kontrolki zawartości; inne zawierają kontrolkę Zawartość dla każdego z dostępnych symboli ContentPlaceHolder. Jeśli nasza nowa strona wzorcowa (Alternate.master
) może kiedykolwiek zostać przypisana do tych stron zawartości, które mają kontrolki Zawartość dla wszystkich elementów ContentPlaceHolder w elemecie Site.master
, istotne jest, aby Alternate.master
zawierały również te same kontrolki ContentPlaceHolder co Site.master
.
Aby strona Alternate.master
wzorcowa wyglądała podobnie do mojej (zobacz Rysunek 4), zacznij od zdefiniowania stylów strony wzorcowej w arkuszu AlternateStyles.css
stylów. Dodaj następujące reguły do elementu 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;
}
Następnie dodaj następujący znacznik deklaratywny do elementu Alternate.master
. Jak widać, Alternate.master
zawiera cztery kontrolki ContentPlaceHolder z tymi samymi ID
wartościami co kontrolki ContentPlaceHolder w pliku Site.master
. Ponadto zawiera kontrolkę ScriptManager, która jest niezbędna dla tych stron w naszej witrynie internetowej korzystającej z platformy ASP.NET AJAX.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<link href="AlternateStyles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="MyManager" runat="server">
</asp:ScriptManager>
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx"
Text="Master Pages Tutorials" />
</div>
<div id="navContent">
<asp:ListView ID="LessonsList" runat="server"
DataSourceID="LessonsDataSource">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<asp:HyperLink runat="server" ID="lnkLesson"
NavigateUrl='<%# Eval("Url") %>'
Text='<%# Eval("Title") %>' />
</ItemTemplate>
<ItemSeparatorTemplate> | </ItemSeparatorTemplate>
</asp:ListView>
<asp:SiteMapDataSource ID="LessonsDataSource" runat="server"
ShowStartingNode="false" />
</div>
<div id="mainContent">
<asp:ContentPlaceHolder id="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
<div id="footerContent">
<p>
<asp:Label ID="DateDisplay" runat="server"></asp:Label>
</p>
<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
Testowanie nowej strony wzorcowej
Aby przetestować tę nową stronę wzorcową, zaktualizuj BasePage
metodę klasy OnPreInit
tak, aby MasterPageFile
właściwość została przypisana do wartości "~/Alternate.maser"
, a następnie odwiedź witrynę internetową. Każda strona powinna działać bez błędów z wyjątkiem dwóch: ~/Admin/AddProduct.aspx
i ~/Admin/Products.aspx
. Dodanie produktu do elementu DetailsView powoduje ~/Admin/AddProduct.aspx
NullReferenceException
wyświetlenie kodu z wiersza kodu, który próbuje ustawić właściwość strony wzorcowej GridMessageText
. Podczas odwiedzania ~/Admin/Products.aspx
obiektu InvalidCastException
jest zgłaszany podczas ładowania strony z komunikatem: "Nie można rzutować obiektu typu "ASP.alternate_master", aby wpisać "ASP.site_master".
Te błędy występują, ponieważ Site.master
klasa za kodem zawiera zdarzenia publiczne, właściwości i metody, które nie są zdefiniowane w Alternate.master
programie . Część znaczników tych dwóch stron zawiera dyrektywę odwołującą @MasterType
się do strony wzorcowej Site.master
.
<%@ MasterType VirtualPath="~/Site.master" %>
Ponadto program obsługi zdarzeń Elementu DetailsView ItemInserted
w programie ~/Admin/AddProduct.aspx
zawiera kod, który rzutuje luźno typową Page.Master
właściwość na obiekt typu Site
. Dyrektywa @MasterType
(używana w ten sposób) i rzutowanie w procedurze obsługi zdarzeń ItemInserted
ściśle łączy ~/Admin/AddProduct.aspx
strony i ~/Admin/Products.aspx
ze stroną wzorcową Site.master
.
Aby przerwać to ścisłe sprzężenie, możemy mieć Site.master
i Alternate.master
pochodzić z wspólnej klasy bazowej, która zawiera definicje dla publicznych elementów członkowskich. W związku z tym możemy zaktualizować dyrektywę @MasterType
, aby odwoływać się do tego wspólnego typu podstawowego.
Tworzenie niestandardowej podstawowej klasy strony wzorcowej
Dodaj nowy plik klasy do App_Code
folderu o nazwie BaseMasterPage.vb
i utwórz go na podstawie System.Web.UI.MasterPage
elementu . Musimy zdefiniować metodę RefreshRecentProductsGrid
i GridMessageText
właściwość w BaseMasterPage
programie , ale nie możemy po prostu przenieść ich tam, Site.master
ponieważ członkowie pracują z kontrolkami sieci Web specyficznymi dla Site.master
strony wzorcowej ( RecentProducts
GridView i GridMessage
Label).
To, co musimy zrobić, to skonfigurować BaseMasterPage
w taki sposób, że te elementy członkowskie są tam zdefiniowane, ale są rzeczywiście implementowane przez BaseMasterPage
klasy pochodne (Site.master
i Alternate.master
). Ten typ dziedziczenia jest możliwy przez oznaczenie klasy jako MustInherit
i jej składowych jako MustOverride
. Krótko mówiąc, dodanie tych słów kluczowych do klasy i jej dwóch członków ogłasza, że BaseMasterPage
nie zaimplementowano RefreshRecentProductsGrid
i GridMessageText
, ale jego klasy pochodne będą.
Musimy również zdefiniować PricesDoubled
zdarzenie w elemecie BaseMasterPage
i podać metodę przez klasy pochodne, aby zgłosić zdarzenie. Wzorzec używany w .NET Framework w celu ułatwienia tego zachowania polega na utworzeniu zdarzenia publicznego w klasie bazowej i dodaniu chronionej, zastępowalnej metody o nazwie OnEventName
. Klasy pochodne mogą następnie wywołać tę metodę, aby zgłosić zdarzenie lub zastąpić go w celu wykonania kodu bezpośrednio przed lub po wywołaniu zdarzenia.
Zaktualizuj klasę, BaseMasterPage
aby zawierała następujący kod:
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
Następnie przejdź do Site.master
klasy code-behind i utwórz ją na podstawie BaseMasterPage
metody . Ponieważ BaseMasterPage
zawiera elementy członkowskie oznaczone MustOverride
, musimy zastąpić te elementy członkowskie w tym miejscu w pliku Site.master
. Overrides
Dodaj słowo kluczowe do definicji metody i właściwości. Zaktualizuj również kod, który zgłasza PricesDoubled
zdarzenie w DoublePrice
procedurze obsługi zdarzeń przycisku Click
za pomocą wywołania metody klasy bazowej OnPricesDoubled
.
Po wprowadzeniu tych modyfikacji Site.master
klasa code-behind powinna zawierać następujący kod:
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
Musimy również zaktualizować Alternate.master
klasę "code-behind", aby pochodzić z BaseMasterPage
dwóch elementów członkowskich i zastąpić je MustOverride
. Ale ponieważ Alternate.master
element GridView nie zawiera listy najnowszych produktów ani etykiety, która wyświetla komunikat po dodaniu nowego produktu do bazy danych, te metody nie muszą nic robić.
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
Odwoływanie się do klasy podstawowej strony wzorcowej
Teraz, gdy ukończyliśmy klasę BaseMasterPage
i rozszerzyliśmy dwie strony wzorcowe, naszym ostatnim krokiem jest zaktualizowanie ~/Admin/AddProduct.aspx
stron i ~/Admin/Products.aspx
w celu odwoływania się do tego wspólnego typu. Zacznij od zmiany @MasterType
dyrektywy na obu stronach:
<%@ MasterType VirtualPath="~/Site.master" %>
Do:
<%@ MasterType TypeName="BaseMasterPage" %>
Zamiast odwoływać się do ścieżki pliku, @MasterType
właściwość odwołuje się teraz do typu podstawowego (BaseMasterPage
). W związku z tym silnie typizowana Master
właściwość używana w klasach kodowych obu stron jest teraz typu BaseMasterPage
(zamiast typu Site
). Dzięki tej zmianie ponownie nastąpi ponowne ponowne wprowadzenie ~/Admin/Products.aspx
. Wcześniej spowodowało to błąd rzutowania, ponieważ strona jest skonfigurowana do używania Alternate.master
strony wzorcowej, ale @MasterType
dyrektywa odwołuje się Site.master
do pliku. Ale teraz strona jest renderowana bez błędu. Wynika to z faktu, że strona wzorcowa Alternate.master
może być rzutowania do obiektu typu BaseMasterPage
(ponieważ rozszerza ją).
Istnieje jedna mała zmiana, która musi zostać wprowadzona w ~/Admin/AddProduct.aspx
pliku . Procedura obsługi zdarzeń kontrolki ItemInserted
DetailsView używa zarówno silnie typizowanej Master
właściwości, jak i luźno wpisanej Page.Master
właściwości. Usunęliśmy silnie typizowane odwołanie, gdy zaktualizowaliśmy dyrektywę @MasterType
, ale nadal musimy zaktualizować luźno wpisane odwołanie. Zastąp następujący wiersz kodu:
Dim myMasterPage As Site = CType(Page.Master, Site)
Za pomocą następującej metody rzutowania Page.Master
na typ podstawowy:
Dim myMasterPage As BaseMasterPage = CType(Page.Master, BaseMasterPage)
Krok 4. Określanie strony wzorcowej do powiązania ze stronami zawartości
Nasza BasePage
klasa ustawia obecnie właściwości wszystkich stron MasterPageFile
zawartości na wartość zakodowaną w fazie PreInit cyklu życia strony. Możemy zaktualizować ten kod, aby opierać stronę wzorcową na niektórych czynnikach zewnętrznych. Być może strona wzorcowa do załadowania zależy od preferencji aktualnie zalogowanego użytkownika. W takim przypadku musimy napisać kod w OnPreInit
metodzie , który BasePage
wyszukuje aktualnie odwiedzające preferencje strony wzorcowej użytkownika.
Utwórzmy stronę internetową, która umożliwia użytkownikowi wybranie strony wzorcowej do użycia — Site.master
lub Alternate.master
— i zapisanie tego wyboru w zmiennej sesji. Zacznij od utworzenia nowej strony internetowej w katalogu głównym o nazwie ChooseMasterPage.aspx
. Podczas tworzenia tej strony (lub innych stron zawartości w związku z tym) nie trzeba powiązać jej ze stroną wzorcową, ponieważ strona wzorcowa jest ustawiana programowo w programie BasePage
. Jeśli jednak nie powiążesz nowej strony ze stroną wzorcową, domyślny znacznik deklaratywny nowej strony zawiera formularz internetowy i inną zawartość dostarczoną przez stronę wzorcową. Należy ręcznie zastąpić ten znacznik odpowiednimi kontrolkami zawartości. Z tego powodu łatwiej jest powiązać nową stronę ASP.NET ze stroną wzorcową.
Uwaga
Ponieważ Site.master
i Alternate.master
mają ten sam zestaw kontrolek ContentPlaceHolder, nie ma znaczenia, jaką stronę wzorcową wybierasz podczas tworzenia nowej strony zawartości. W celu zapewnienia spójności proponuję użycie polecenia Site.master
.
Rysunek 05. Dodawanie nowej strony zawartości do witryny internetowej (kliknij, aby wyświetlić obraz pełnowymiarowy)
Zaktualizuj plik, Web.sitemap
aby uwzględnić wpis dla tej lekcji. Dodaj następujący znacznik poniżej <siteMapNode>
strony wzorcowej i ASP.NET LEKCJI AJAX:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
Przed dodaniem dowolnej zawartości do ChooseMasterPage.aspx
strony należy chwilę zaktualizować klasę za pomocą kodu strony, aby mogła pochodzić z BasePage
klasy (a nie System.Web.UI.Page
). Następnie dodaj kontrolkę DropDownList do strony, ustaw jej ID
właściwość na MasterPageChoice
, i dodaj dwie wartości ListItems z wartościami Text
"~/Site.master" i "~/Alternate.master".
Dodaj kontrolkę Sieć Web przycisku do strony i ustaw jej ID
Text
właściwości odpowiednio na SaveLayout
i "Zapisz wybór układu". Na tym etapie deklaratywne znaczniki strony powinny wyglądać podobnie do następujących:
<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>
Gdy strona zostanie po raz pierwszy odwiedzona, musimy wyświetlić aktualnie wybraną stronę wzorcową użytkownika. Utwórz procedurę obsługi zdarzeń Page_Load
i dodaj następujący kod:
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
Powyższy kod jest wykonywany tylko podczas pierwszej wizyty na stronie (a nie w kolejnych postbackach). Najpierw sprawdza, czy zmienna MyMasterPage
sesji istnieje. Jeśli tak, próbuje znaleźć pasujący listItem na liście rozwijanej MasterPageChoice
. Jeśli zostanie znaleziony pasujący element ListItem, jego Selected
właściwość jest ustawiona na True
wartość .
Potrzebujemy również kodu, który zapisuje wybór użytkownika w zmiennej MyMasterPage
Sesja. Utwórz procedurę obsługi zdarzeń dla SaveLayout
zdarzenia przycisku Click
i dodaj następujący kod:
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
Uwaga
Po wykonaniu Click
procedury obsługi zdarzeń po powrocie zwrotnej strona wzorcowa została już wybrana. W związku z tym wybór listy rozwijanej użytkownika nie będzie obowiązywać do czasu kolejnej wizyty strony. Wymusza Response.Redirect
ponowne żądanie ChooseMasterPage.aspx
w przeglądarce .
Po zakończeniu ChooseMasterPage.aspx
strony naszym ostatnim zadaniem jest BasePage
przypisanie MasterPageFile
właściwości na podstawie wartości zmiennej MyMasterPage
Sesja. Jeśli zmienna sesji nie jest ustawiona, ma wartość domyślną BasePage
Site.master
.
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
Uwaga
Przeniesiono kod, który przypisuje Page
właściwość obiektu MasterPageFile
poza OnPreInit
procedurę obsługi zdarzeń i do dwóch oddzielnych metod. Ta pierwsza metoda SetMasterPageFile
, przypisuje MasterPageFile
właściwość do wartości zwróconej przez drugą metodę GetMasterPageFileFromSession
. Oznaczyłem metodę Overridable
takSetMasterPageFile
, aby przyszłe klasy rozszerzające BasePage
mogły opcjonalnie zastąpić ją w celu zaimplementowania logiki niestandardowej w razie potrzeby. W następnym samouczku zobaczymy przykład zastępowania BasePage
właściwości .s SetMasterPageFile
.
Za pomocą tego kodu odwiedź ChooseMasterPage.aspx
stronę. Site.master
Początkowo jest zaznaczona strona wzorcowa (patrz Rysunek 6), ale użytkownik może wybrać inną stronę wzorcową z listy rozwijanej.
Rysunek 06. Strony zawartości są wyświetlane przy użyciu strony wzorcowej Site.master
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 07. Strony zawartości są teraz wyświetlane przy użyciu strony wzorcowej Alternate.master
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Podsumowanie
Po odwiedzeniu strony zawartości jej kontrolki Zawartość są połączone z kontrolkami ContentPlaceHolder strony wzorcowej. Strona wzorcowa strony zawartości jest oznaczona właściwością Page
klasy MasterPageFile
, która jest przypisywana do @Page
atrybutu dyrektywy MasterPageFile
podczas etapu inicjowania. Jak pokazano w tym samouczku, możemy przypisać wartość do MasterPageFile
właściwości, o ile to zrobimy przed końcem etapu PreInit. Możliwość programowego określenia strony wzorcowej powoduje otwarcie drzwi dla bardziej zaawansowanych scenariuszy, takich jak dynamiczne powiązanie strony zawartości ze stroną wzorcową na podstawie czynników zewnętrznych.
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:
- Diagram cyklu życia strony ASP.NET
- Przegląd cyklu życia strony ASP.NET
- omówienie motywów i skórek ASP.NET
- Strony wzorcowe: porady, wskazówki i pułapki
- Motywy w ASP.NET
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 dotrzeć pod mitchell@4GuysFromRolla.com adresem lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka był Suchi Banerjee. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi linię na mitchell@4GuysFromRolla.com
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla