一、 簡介
任何由多個頁面組成的網站都需要某種導航用戶接口,這是用兩步來創建的。首先,必須定義站點的邏輯結構;然後,添加用戶接口元素來允許用戶在站點結構的各個部分之間來回移動。在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)把用戶引導到他們所請求的頁面上去。