ASP.NET2.0中層次數據的處理

推薦:ASP.NET數據庫編程知識庫
數據源控件可以同時暴露平面表格式的或層次的數據。前面演示的SqlDataSource和ObjectDataSource控件都是平面表格式的數據源控件。ASP.NET 2.0還包含兩個層次數據源控件:用于連接XML文件的XmlDataSource和用于連接站點導航數據的SiteMapDataSource。這一部分將介紹這些控件的使用技術。
TreeView和Menu控件
數據綁定控件與數據源控件類似,也可以是層次的。表格式數據綁定控件顯示數據列表或表格,層次數據綁定控件能夠用遞規方式獲取層次數據,在UI中用父-子關系顯示數據。ASP.NET 2.0中的分層數據綁定控件的例子有TreeView和Menu控件。下面將介紹把這些控件綁定到層次數據源的一些技術,包括很多示例。
綁定到XML
XmlDataSource控件允許其它控件綁定到XML數據。XmlDataSource支持DataFile屬性,它被用于指定作為輸入(input)的XML數據文件的路徑。你還可以指定TranformFile屬性,給數據應用XSLT轉換;設置XPath屬性來指定需要暴露的數據源節點的子集。
下面的例子演示了一個通過XmlDataSource控件綁定到XML文件的TreeView控件。這個TreeView把每個TreeNode對象的屬性與分層樹中的XML節點的屬性關聯起來了(為了進行數據綁定,XML節點的屬性都被處理為數據項的屬性)。在默認情況下,TreeView控件通過調用對象的ToString()方法簡單地顯示數據項。它顯示了XML節點的元素(element)名稱,這樣你就可以看到TreeView所綁定的節點層次。它不一定能夠顯示出你所需要的內容,但它提供了一個很好的出發點,未來你將更容易定制XML數據的顯示方式。
| <asp:XmlDataSource ID="MySource" DataFile="'/App_Data/Bookstore.xml" runat="server"/> <asp:TreeView ID="TreeView1" SkinId="Bookstore" DataSourceId="MySource" ExpandDepth="3" MaxDataBindDepth="3" runat="server" /> |
為了讓TreeView顯示更有意義的內容,你可以為樹中的每個節點指定不同的數據綁定。為了定義層次數據項的字段如何映射到TreeNode屬性,你可以把TreeNodeBinding對象添加到TreeView的Databindings集合中。TreeNodeBinding的兩個重要屬性決定了如何在層次數據項集合上使用綁定。DataMember屬性指定了數據項的類型或者XML數據中用于綁定的元素名稱。Depth屬性指定了應用于層次樹的數據綁定的深度。你可以設置DataMember或Depth,或者兩個屬性都設置。例如,如果要定義XML文件中的所有Book元素的數據綁定,只需要把DataMember設置為"Book"。為了定義所有深度為1的節點的數據綁定,只需要把Depth設置為1。如果要定義深度為1的所有Book節點,需要把TreeNodeBinding對象的DataMember設置為"Book",同時把Depth設置為1。
當你設置了DataMember或Depth用于匹配節點集合之后,就可以定義TreeNodeDataBinding的另外一些屬性來定制數據項的屬性(或XML數據中的XML節點屬性)如何映射到TreeView控件的TreeNode的屬性。例如,TextField屬性定義了顯示為TreeNode文本的屬性名稱;類似地,ValueField屬性定義了作為TreeNode值的數據項屬性;NavigateUrlField屬性定義了TreeNode導航鏈接的字段/屬性,等等。你還可以為一個已有數據綁定的TreeNode屬性指定靜態值。例如,指定Book元素的TreeNode使用"Book.gif"圖像、設置DataMember屬性是"Book"的TreeNodeBinding的ImageUrl屬性。
下面的例子演示了一個綁定到XML數據的TreeView,數據綁定只應用在XML層次樹的特定元素上。
| <Databindings> <asp:TreeNodeBinding DataMember="Bookstore" Text="Bookstore" ImageUrl="'/images/xp/folder.gif" /> <asp:TreeNodeBinding DataMember="genre" TextField="name" ImageUrl="'/images/xp/folder.gif" /> </Databindings> |
XmlDataSource支持XPath屬性,你可以用它來過濾數據源所暴露的節點集合。在下面的例子中,Xpath屬性被設置為Bookstore/genre[@name='Business']/book,以過濾數據源的節點,僅顯示"Business"類型下的book元素。在指定XPath屬性的語法時要特別小心,否則可能出現數據源任何節點都不暴露的情況(相關的數據綁定控件也不會顯示)。
| <asp:XmlDataSource ID="MySource" DataFile="'/App_Data/Bookstore.xml" XPath="Bookstore/genre[@name='Business']/book" runat="server"/> |
請注意,TreeView樹準確地匹配了源XML中的層次。由于這個原因,通常會為了綁定到TreeView而具體構造XML,或者為了綁定到TreeView而使用XSL轉換重新把數據構造為適當的分層結構。
| <asp:XmlDataSource ID="MySource" DataFile="'/App_Data/Bookstore2.xml" TransformFile="'/App_Data/Bookstore2.xsl" XPath="Bookstore/genre[@name='Business']/book" runat="server"/> |
把表格式數據綁定控件綁定到分層數據源也是可行的,但是它只能顯示第一層數據。在下面的例子中,模板化的DataList控件綁定到bookstore XML文件。由于數據源暴露的頂層節點是<book/>節點,DataList可以在自己的ItemTemplate模板中使用Eval數據綁定語法綁定到這些節點的屬性。
| <asp:DataList id="MyDataList" DataSourceId="MySource" runat="server"> <ItemTemplate> <img alt="Cover Image" src='<%#"images/" + Eval("ISBN") + ".gif"%>'> <%# Eval("Title") %> ISBN: <%# Eval("ISBN") %> Price: <%# Eval("Price") %> </ItemTemplate> </asp:DataList> |
雖然只顯示一層也是有用的,但是如果能夠用嵌套的表格式數據綁定控件來顯示下面的層次應該會更好。幸運的是,ASP.NET 2.0允許你實現這種功能。除了Eval數據綁定語法之外,ASP.NET 2.0還提供了基于XPath的數據綁定語法,在實現了IXPathNavigable接口的任何數據項上都可以使用它。有兩種可用的表達式類型:
· XPath(expression, [formatString]) - 根據數據項計算Xpath表達式的值,返回單個值。
· XPathSelect(expression, [formatString]) - 根據數據項計算Xpath表達式的值,返回節點列表。
下面的例子是建立在前面的例子基礎之上的,它用Xpath數據綁定表達式代替Eval表達式綁定到book節點的屬性。從表面上看,這樣的操作與每個表達式的"@"前綴相比沒有什么更多功能,只是用于引用節點屬性的Xpath語法。但是,Xpath的真正靈活性就是依賴于這種引用層次中的任意項(不僅僅是屬性)的能力的。
這個示例給外部DataList的ItemTemplate模板另外增加了一個DataList,并把這個內部DataList的屬性綁定到一個描述當前book節點的chapter子節點的XPathSelect表達式。在內部DataList的ItemTemplate模板中,Xpath數據綁定表達式根據這些"chapter"內容節點來計算值。ASP.NET 2.0利用這種技術,使你能夠通過組合表格式數據綁定控件簡便地構造出豐富的、分層的數據顯示方式。
| <asp:DataList id="MyDataList" DataSourceId="MySource" runat="server"> <ItemTemplate> <img alt="Cover Image" src='<%# "images/" + XPath("@ISBN") + ".gif" %>'> <%# XPath("@Title") %> ISBN: <%# XPath("@ISBN") %> Price: <%# XPath("@Price") %> <asp:DataList id="MyDataList" DataSource='<%# XPathSelect("chapter") %>' runat="server"> <ItemTemplate> Chapter <%# XPath("@num") %>: <%# XPath("@name") %> <%# XPath(".") %> </ItemTemplate> </asp:DataList> </ItemTemplate> </asp:DataList> |
為了處理數據綁定控件對特定位置的節點的請求,XmlDataSource等層次數據源控件讓層次中的每個節點與唯一的路徑相對應。這樣就帶來了一些特性,例如TreeView的按需求填充(PopoulateOnDemand)特性,當某個節點被擴展的時候,來自數據源的節點才被發送到客戶端,而不是一次性地發送所有的節點。它也允許你在頁面代碼中用這種方式配置數據源來顯示特定位置的節點。不同的數據類型的路徑語法是不同的,而且不能在代碼中構造。但是,你可以使用TreeNode的DataPath屬性來訪問綁定到TreeView的節點的數據路徑。由于XmlDataSource把Xpath表達式作為自己的數據路徑語法,這些路徑也可以指定給XmlDataSource的Xpath屬性來進行節點列表的過濾。下面的例子演示了 這種技術,它使用XmlDataSource實現了一個主-從表。例子中有兩個XmlDataSource控件,其中一個綁定到TreeView(主表控件),另一個綁定到DataList(從表控件)。當用戶點擊TreeView節點的時候,就檢索它的DataPath屬性,并把它賦予綁定到DataList的XmlDataSource控件,以顯示被點擊的節點的詳細信息。
| Sub MyTreeView_SelectedNodeChanged(sender As Object, e As EventArgs) Dim path As String = MyTreeView.SelectedNode.DataPath MyDetailsSource.XPath = path MyDataList.DataSource = MyDetailsSource MyDataList.DataBind() End Sub |