Při tvorbě složitějších webových aplikací je potřeba, aby všechny stránky aplikace měly stejný vzhled a několik společných částí, které se budou chovat na všech stránkách stejně. Ve starší verzi ASP.NET se tento problém obvykle řeší přidáváním ovládacích prvků, které obsahují tyto společné části, do každé stránky aplikace. V nové verzi ASP.NET je možné tento problém řešit pomocí „master pages“.

Webové aplikaci se vytvoří jedna master page, která obsahuje společné prvky a má vyznačená místa, do kterých lze vkládat obsah. Ostatní stránky (content pages) poté k master page doplňují pouze požadovaný obsah.

Pokud si chcete při čtení článku procházet zdrojové kódy, nebo se podívat jak aplikace fungují, jsou vám k dispozici.

Základy práce s Master Pages

V následující ukázce vytvoříme jednu master page a jednu stránku, která bude dodávat k této stránce obsah (vše bude hned vysvětleno).

Master page

<!– MasterPage.master –>
<%@ Master Language=“C#“ %>
<html><head runat=“server“>
   <title>Master pages demo</title>
</head><body>
<form id=“form1″ runat=“server“>
   <!– Cast spolecna pro vsechny stranky –>
   <h1>Nadpis z master page</h1>
   <div id=“menu“>
      <a href=“first.aspx“>Prvni stranka</a>
      <a href=“second.aspx“>Druha stranka</a>
   </div>
   <!– Zde se bude vkladat obsah stranek –>
   <asp:contentplaceholder id=“mainContent“ runat=“server“>
   </asp:contentplaceholder>
</form>
</body></html>

Tato master page vypadá na první pohled jako úplně obyčejná ASP.NET stránka. Jediné rozdíly jsou v tom, že soubor má místo přípony aspx příponu master a místo direktivy Page obsahuje direktivu Master. Vnitřně existuje ještě jeden rozdíl, a sice že normální stránka je potomkem třídy System.­Web.­UI.­Page a master page dědí od System.­Web.­UI.­MasterPage. V master page může být, kromě libovolných ostatních ovládacích prvků, jeden nebo více prvků asp:ContentPlaceHolder, které určují místa, kam mohou stránky s obsahem (content pages) vkládat obsah.

Content page

<!– First.aspx –>
<%@ Page Language=“C#“ Title=“Hello world“
      MasterPageFile=“~/MasterPage.master“ %>
<!– Vlozit obsah do ContentPlaceHolderu –>
<asp:Content ContentPlaceHolderID=“mainContent“ runat=“server“>
   Hello world from First.aspx!
</asp:Content>

Tato content page doplňuje obsah do master page, která je určena v direktivě Page, a to pomocí atributu MasterPageFile. Dále je do direktivy Page přidán atribut Title, protože samotný element title se nachází v master page a není tedy možné titulek nastavovat přímo (z tohoto důvodu je také potřeba, aby element head v master page obsahoval runat="server"). Jednotlivé fragmenty stránky se do master page vkládají pomocí ovládacího prvku asp:Content, kterému je potřeba předat ID ContetnPlaceHolderu z master page pomocí atributu ContetnPlaceHolderID.

Výchozí obsah části

Kromě rozložení a chování společných ovládacích prvků lze v master page také určit výchozí obsah jednotlivých částí, který se použije, pokud v content page nebude asp:Content s ContentPlaceHolderID odpovídají části. Takto lze například vytvořit menu, které bude na většině stránek stejné, ale v případě potřeby může být u nějaké stránky mírně upravené. Výchozí obsah částí se vkládá v master page dovnitř tagu asp:ContentPlaceHolder, jak je vidět v následující ukázce:

<!– Zde se bude vkladat menu stranky –>
<asp:contentplaceholder id=“menuContent“ runat=“server“>
   <!– Vychozi odkazy v menu, ktere je mozne zmenit –>
   <a href=“first.aspx“>Prvni stranka</a>
   <a href=“second.aspx“>Druha stranka</a>
</asp:contentplaceholder>

Podpora ve Visual Studiu 2005

Nová verze Visual Studia prošla řadou velmi podstatných změn. Nejzásadnější změnou je, že se Visual Studio snaží v co nejmenší míře zasahovat do kódu napsaného při tvorbě stránky ručně. Dále Visual Studio generuje kód, který je nejen validní XHTML, ale i přehledný. Díky tomu je také zajímavá jeho podpora pro master pages, protože dokáže usnadnit mnoho obvyklých operací.

Stránky master pages je možné přidávat do projektu pomocí dialogu „Add new item“ a při přidávání aspx stránky je možné rovnou vybrat master page, která se má pro stránku používat. Po otevření master page v „design view“ lze do stránky přidávat kromě obvyklých ovládacích prvků i ovládací prvky typu asp:ContentPlaceHolder. Další příjemnou změnou je, že ovládací prvky lze z panelu nástrojů přetahovat nejen při zobrazení v „design view“, ale i v „code view“.

Content page ve Visual Studiu
Stránka používající master page ve Visual Studiu 2005

Při otevření stránky, které používá master page, Visual Studio nalezne danou master page a zobrazí stránku přesně tak, jak se bude zobrazovat ve webovém prohlížeči. Všimněte si, že obsah, který se načítá z master page, je zobrazen šedivě a není možno ho upravovat. Měnit lze pouze části stránky, které jsou do master page vkládány, a pokud stránka ještě neobsahuje prvky asp:Content pro daný asp:ContentPlaceHolder, lze je rovnou v „design view“ přidat.

Komplikovanější stránky

Vnořené master pages

Při tvorbě komplikovanější aplikace může být potřeba, aby měly všechny stránky společnou pouze hlavičku a patičku, a zbývající části se dále lišily podle toho, v jaké části aplikace se stránka nachází. Toho je možno dosáhnout vytvořením vnořených master pages. Ve zkratce vše funguje tak, že vytvoříme jednu master page, která bude obsahovat prvky společné pro všechny stránky (například Global.master), a dále několik dalších master pages, které mají jako master page nastavenu stránku Global.master. V těchto stránkách se přidají prvky specifické pro jednotlivé sekce aplikace a prvky typu asp:ContentPlaceHolder, do kterých se bude vkládat samotný obsah.

Nested master pages
Možné použití vnořených master pages ve složité aplikaci

Vytvoření master page, které dědí vzhled od hlavni master page, není složité. Stačí vytvořit obvyklou master page a do direktivy Master přidat atribut MasterPageFile, kterým určíme stránku, od níž chceme master page odvozovat. Poté stačí odstranit obsah stránky a nahradit ho jedním nebo více ovládacími prvky asp:Content se správně nastavenými vlastnostmi ContentPlaceHolderID. V místech, kam budou obsah dodávat jednotlivé content pages, stačí vložit již známý prvek asp:ContentPlaceHolder.

<!– Master page, ktera je odvozena od Global.master –>
<%@ Master Language=“C#“ MasterPageFile=“~/Global.master“ %>
<asp:Content ContentPlaceHolderID=“mainContent“ runat=“server“>
   <!– Cast spolecna pro vsechny odvozene stranky –>
   <b>Produkty:</b>
   <a href=“product1.aspx“>Prvni produkt</a>
   <a href=“product2.aspx“>Druhy produkt</a>
   <!– Cast ktera se bude v odvozenych strankach menit –>
   <asp:ContentPlaceHolder ID=“productsContent“ runat=“server“>
   </asp:ContentPlaceHolder>
</asp:Content>

Volba master page podle zařízení

Další užitečnou vlastností master pages je možnost načítat různou master page pro různá zařízení nebo webové prohlížeče. Tato vlastnost existuje v ASP.NET 2 hlavně kvůli podpoře mobilních zařízení, ale lze ji použít i k odlišení prohlížečů. Seznam všech zařízení a prohlížečů je uložen v podadresáři CONFIG\Browsers adresáře, kam se instaluje .NET Framework. Identifikace zařízení a prohlížečů je rozdělena do více souborů, takže je možné velmi snadno přidávat nové.

Jiná master page pro různé prohlížeče
Jiná master page pro různé prohlížeče

Specifická master page pro různá zařízení se nastavuje v direktivě Page, a to pomocí atributu MasterPageFile, před který se přidá dvojtečkou oddělená předpona odpovídající „id“ prohlížeče nastavenému ve výše uvedeném konfiguračním adresáři. Následující příklad načítá zvláštní master page (IeMaster.master) pro prohlížeče založené na Microsoft Internet Exploreru:

<!– Rozliseni master page podle zarizeni/prohlizece –>
<%@ Page Language=“C#“ Title=“Ukazkova stranka“
      MasterPageFile=“~/Master.master“
      Ie:MasterPageFile=“~/IeMaster.master“ %>

Nastavení master page ve web.config

Pokud víte, že ve své aplikaci budete používat master page na všech stránkách, můžete ji nastavit globálně pomocí konfiguračního souboru. Takto nastavená master page se automaticky použije pro všechny stránky, které obsahují ovládací prvky typu asp:Content (tedy je zřejmé, že vyžadují nastavení master page). Pokud do aplikace přidáte stránku, která bude obsahovat obvyklý XHTML kód, nebude na ní master page použita. Výchozí nastavení je možné potlačit také uvedením jiné master page v direktivě Page (atribut MasterPageFile), poté se místo výchozí stránky použije tato nově nastavená. Následující ukázka obsahuje část konfiguračního souboru, která nastavuje Default.master jako výchozí master page:

<?xml version=“1.0″ ?>
<configuration>
<system.web>
   <!– Nastavi master page pro vsechny stranky –>
   <pages masterPageFile=“Default.master“ />
</system.web>
</configuration>

Přístup k Master page z kódu

Přístup k datům v master page

Doposud jsme ve všech příkladech pracovali pouze s ASP.NET a XHTML značkami. Je tedy na čase ukázat, jak lze s master pages manipulovat přímo ze zdrojového kódu stránek. Přestože kód, který pracuje s ovládacími prvky v master page, by sám měl být také v master page, může být potřeba přistupovat k master page z kódu jednotlivých odvozených stránek. K tomu slouží vlastnost Master, která vrací objekt typu MasterPage reprezentující stránku. Pro usnadnění přístupu ke stránce je možné definovat typ master page (buď pomocí souboru master nebo pomocí jména codebehind třídy). Pokud je takto určen typ stránky, vrací vlastnost Master přímo objekt dané stránky.

Následující kód ukazuje master page obsahující ovládací prvek, ve kterém si uživatel může vybrat z několika možností. Vybraná možnost je zpřístupněna pomocí vlastnosti SelectedOption:

<%@ Master Language=“C#“%>
<script runat=“server“>
   // Vlastnost vraci text vybrane polozky
   public string SelectedOption
   {
      get { return listChoose.SelectedItem.Value; }
   }
</script>
<form id=“form“ runat=“server“>
   <!– Zde si muze uzivatel neco zvolit –>
   <asp:DropDownList runat=“server“ ID=“listChoose“>
      <asp:ListItem>Prvni moznost</asp:ListItem>
      <asp:ListItem>Druha moznost</asp:ListItem>
   </asp:DropDownList>
   <!– ContentPlaceHolder pro vkladani obsahu –>
</form>

V následující stránce, která používá výše uvedenou master page, budeme při načtení stánky zjišťovat vybranou možnost zpřístupněnou pomocí SelectedOption. Všimněte si direktivy MasterType, která určuje typ master page, a proto není při zjišťování vybrané položky v master page potřeba přetypování.

<!– Direktiva MasterType urcuje typ master page –>
<%@ Page Language=“C#“ Title=“Prvni stranka“
      MasterPageFile=“~/MasterPage.master“ %>
<%@ MasterType VirtualPath=“~/MasterPage.master“ %>
<script runat=“server“>
   // Zjistuje vybranou moznost z master page
   void Page_Load(object sender, EventArgs e)
   {
      lblOption.Text=Master.SelectedOption;
   }
</script>
<asp:Content …>
   Vybrana moznost je <asp:Label ID=“lblOption“ Runat=“server“ />
</asp:Content>

Dynamické načítání master page

Již jsem zmínil, že je možné master page volit podle zařízení nebo webového prohlížeče. Někdy ale může být potřeba, aby se master page volila podle nějakých složitějších pravidel (například aplikace, která běží pod několika různými doménami, může mít pro každou doménu různý vzhled), proto je možné načítat master page dynamicky před samotným načítáním stránky. V nové verzi ASP.NET přibyla událost PreInit, která se volá předtím, než se začne stránka načítat. V té chvíli je také možno měnit master page, která se má pro stránku použít (pokud se pokusíte měnit master page později, dostanete výjimku). Následující ukázka náhodně volí jednu ze dvou master pages:

// Zvolit nahodne Master1 nebo Master2
void Page_PreInit(object sender, EventArgs e)
{
   Random r=new Random();
   if (r.Next(2)==0)
      MasterPageFile=“~/Master1.master“;
   else
      MasterPageFile=“~/Master2.master“;
}

Průběh zpracovávání událostí

Při načítání stránky používající master page se vytváří objekt samotné stránky, ale také objekt master page. Proto je dobré vědět, že události, které mohou být vyvolány v objektu obou stránek (jako je například Page_Load), jsou vyvolány nejprve ve stránce s obsahem a až poté v master page.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět