一、 簡介
任何由多個頁面組成的網站都需要某種導航使用者接口,這是用兩步驟來創建的。首先,必須定義網站的邏輯結構;然後,新增使用者介面元素來允許使用者在網站結構的各個部分之間來回移動。在ASP.NET 2.0以前,請開發者自己來解決這兩個問題。然而,到了版本2.0以後,ASP.NET提供了一個簡單的方法來定義一站點的結構並且包括大量的Web控件-專門設計來顯示站點導航用戶接口。
在上一篇中我們分析瞭怎樣透過導航Web控制項來建立Web.sitemap XML網站地圖檔案以及如何顯示網站導航信息,這包括:
·SiteMapPath,它顯示一個breadcrumb(Home>Electronics>XBOX)
·TreeView,它顯示一個可折迭的垂直顯示的樹,用於顯示整個站點地圖層次
·Menu,它顯示一個水平或垂直對齊的菜單
上一篇中只對站點地圖文件和導航Web控件的功能和能力提供了一個粗略介紹。在這一部分裡,我們將把注意力轉到編程地控制網站地圖信息,並詳細地分析一下SiteMapPath導航Web控制項。
二、 網站地圖
本文中的範例使用在第一部分所建立的網站地圖。你可以在第一部分看到該網站地圖XML檔案的精確的句法或在本文最後下載下來。站點結構的圖形化表示使用於這些範例中,請參閱下圖:
三、 程式控制站點地圖
一個站點地圖是一個相關聯的站點地圖結點的集合。典型地,每個網站地圖結點包含一個標題,一個URL和一個描述。上面顯示的圖像是網站地圖的一個範例,其中每個矩形代表一個網站地圖結點。 ASP.NET並沒有要求一個特別的格式來指定網站地圖,儘管它的確提供了使用一XML格式檔案的預設選擇。 (關於XML檔案的細節請參考第一篇)
ASP.NET提供了一個類別稱為SiteMap-它提供唯讀的,程式設計地存取該網站地圖。這個類別被兩個控制項內部使用,在本文的後面我們將分析這兩個類別:
·SiteMapPath-基於被存取頁面和它的網站結構位置產生一個breadcrumb。具體地說,該SiteMapPath從由SiteMap.CurrentNode屬性傳回的結點開始,往上遍歷這個層次結構直到根部。
·SiteMapDataSource-這個控制項建立一個層次結構的資料來源-它對應到該網站地圖的結構。為了在另外的Web控制項中顯示網站地圖信息,例如TreeView或Menu,該Web控制項並不會直接查詢網站地圖;而是,它們綁定到一個SiteMapDataSource控制項-它負責讀取該網站地圖結構。
SiteMap類別有兩個屬性:RootNode和CurrentNode。這兩個屬性都會傳回SiteMapNode實例。 SiteMapNode類別代表一個定義在網站地圖中的結點並且具有描述該結點的屬性-Title,Url和Description,另外還有透過程式控制層次結構的屬性-ParentNode,ChildNodes,NextSibling,PreviousSibling,等等。
你可以在自己的自己ASP.NET頁中使用SiteMap類別。例如,我們能在每個頁面中顯示Next,Previous和Up連結-這只需透過添加三個HyperLink控製到網站的主頁面,另加上一點點編程以檢查是否CurrentNode有一NextSibling,PreviousSibling或ParentNode。具體地說,你將會加入下列標記到你的主頁:
[<asp:HyperLink ID="lnkPrev" runat="server">Prev</asp:HyperLink>] |
[<asp:HyperLink ID="lnkUp" runat="server">Up</asp:HyperLink>] |
[<asp:HyperLink ID="lnkNext" runat="server">Next</asp:HyperLink>]
主頁面的Page_Load事件處理器看起來如下:
If SiteMap.CurrentNode IsNot Nothing Then
'設定next/previous/up連結If SiteMap.CurrentNode.PreviousSibling IsNot Nothing Then
lnkPrev.NavigateUrl = SiteMap.CurrentNode.PreviousSibling.Url
lnkPrev.Text = "< Prev (" & SiteMap.CurrentNode.PreviousSibling.Title & ")"
Else
lnkPrev.NavigateUrl = String.Empty
lnkPrev.Text = "< Prev"
End If
If SiteMap.CurrentNode.ParentNode IsNot Nothing Then
lnkUp.NavigateUrl = SiteMap.CurrentNode.ParentNode.Url
lnkUp.Text = "Up (" & SiteMap.CurrentNode.ParentNode.Title & ")"
Else
lnkUp.NavigateUrl = String.Empty
lnkUp.Text = "Up"
End If
If SiteMap.CurrentNode.NextSibling IsNot Nothing Then
lnkNext.NavigateUrl = SiteMap.CurrentNode.NextSibling.Url
lnkNext.Text = "(" & SiteMap.CurrentNode.NextSibling.Title & ") Next >"
Else
lnkNext.NavigateUrl = String.Empty
lnkNext.Text = "Next >"
End If
End If
這將把三個超級連結Next,Up和Previous加入到從主頁面繼承的每一個頁面,參見下圖的快照。
四、 用SiteMapPath控制項顯示Breadcrumbs
SiteMapPath控制項顯示一個breadcrumb-它用於向使用者顯示他們在該網站結構中所處的位置。 SiteMapPath控制項的輸出由下列三個因素決定:
·網站的結構,由網站地圖定義,
·被造訪的頁面和
·SiteMapPath控制項的屬性值
當造訪一個有SiteMapPath控制項的頁面時,該SiteMapPath控制項試圖把頁面的URL對應到定義在該網站地圖中的一個網站地圖結點的url值。如果找到一個匹配,則該控制項將上行遍歷該結構到根部,並作下列輸出:RootNode>ParentNode>...>ParentNode>CurrentNode。這裡的CurrentNode是網站地圖結點的標題-它用來映射當前頁面請求的URL;RootNode和ParentNodes被作為超級連結生成,如果該網站地圖結點有一個定義在該網站地圖中的URL值。在"History Books"頁面(Books/History.aspx)中的一個SiteMapPath控制項將產生Home>Books>History,同時也分別產生超級連結形式的Home和Books,分別回指向Default.aspx和Books/Default.aspx 。在存取Books/Default.aspx時,SiteMapPath會產生Home>Books。
非常清楚,SiteMapPath的輸出既依賴網站地圖本身又依賴正在被造訪的頁面。此SiteMapPath的輸出可以被自訂,透過該控制項的屬性。有一些標準Web控制格式的屬性-BackColor,Font,ForeColor,等等-還有一些特定於SiteMapPath的設置,包括:
u PathDirection-可以取兩個值之一它們是RootToCurrent(缺省的)或CurrentToRoot。當取值為RootToCurrent,在"History Books"頁面的breadcrumb產生為Home>Books>History;當取值為CurrentToRoot,輸出將會是History>Books>Home。
·PathSeparator-指定用於分開breadcrumb中的每個結點的字串;預設為>
·RenderCurrentNodeAsLink-一個Boolean屬性-它指定是否CurrentNode應該產生為一個連結;缺省為False。
·ParentLevelsDisplayed-一個整數值-它可以用來限制breadcrumb所顯示樹層結構的高度。缺省地,這個屬性值為-1,這意味著沒有限制;把它的值置為1,那麼在"History Books"頁面將產生breadcrumb Books>History。根不包含在內,因為SiteMapPath控制項只是向上遍歷到一個父級-從"History"到"Book"。
·ShowToolTips-如果一站點地圖結點有一個描述值,那麼該描述對於每一個breadcrumb結點被顯示為一個提示文本,如果這個屬性被設定為True(預設情況)。
還有風格屬性可用來設定BackColor,Font,ForeColor,等等-用於SiteMapPath控制項的各個部分。可以使用NodeStyle屬性來客製化在breadcrumb中的結點的外觀;可以使用RootNodeStyle和CurrentNodeStyle來進一步客製化在breadcrumb中的第一個和最後一個結點。一般地,最簡單也是最具有美學特點的來格式化該SiteMapPath控制項的方法是使用它的"Auto Format"精靈-這可以透過該控制項的靈敏標籤啟動。
五、 用模板定制生成的輸出
該SiteMapPath包含四個模板-它們允許進一步定制生成的輸出。範本允許混合使用靜態HTML標記,Web控件和資料綁定語法;如果你以前已使用了DataList或Repeater控件,那麼你已對模板很熟悉了。在ASP.NET 2.0中的模板基本上同ASP.NET 1.x中的一樣,除了ASP.NET 2.0引入了一些新的更精練的語法來資料綁定表達式外。例如,在ASP.NET 1.x中,你必須使用語法<%# DataBinder.Eval(Container.DataItem, PropertyName) %>來取得一列的值。而在ASP.NET 2.0中,這種老式的語法仍可以使用,但是你可以選擇性地使用更短的版本<%# Eval(PropertyName) %>。
預設地,SiteMapPath以常規超級連結方式產生根和父結點,這樣當使用者點擊該連結時,他們可以在該控制項層次樹上快速地向上回退。然而,在把資訊傳回使用者之前,你可能想做一些伺服器端處理-也許你想要記錄下使用者要到哪裡去或自動地保存他們在該頁面所做的任何變更。可以透過使用一個模板和把該結點生成為一個LinkButton來實現這一功能。
例如,如果你只想要把SiteMapPath的根結點產生為一個LinkButton,你可以用下面的標記來把一個<RootNodeTemplate>加到SiteMapPath控制項上:
<asp:SiteMapPath ID="SiteMapPath1" runat="server" >
<RootNodeTemplate>
<asp:LinkButton ID="LinkButton1" runat="server"
Text='<%# Eval("title") %>'
CommandArgument='<%# Eval("url") %>'
OnCommand="LinkButton1_Command">
</asp:LinkButton>
</RootNodeTemplate>
</asp:SiteMapPath>
這個標記加入一LinkButton控制項到SiteMapPath-它的Text屬性被分配給對應SiteMapNode的Title屬性。當點擊該LinkButton時,將導致一個回寄並且該控制項的Command事件激發-這將啟動LinkButton1_Command事件處理器。 SiteMapNode的Url屬性被透過CommandArgument屬性傳遞到這個事件處理器。在這個事件處理器中,你可以做任何伺服器端所需的處理,然後透過Response.Redirect(e.CommandArgument)把使用者引導到他們所要求的頁面上去。