ASP.NET 2.0中層次資料的處理

來源:互聯網
上載者:User
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
  綁定到網站導覽資料(Site Navigation)

  網站導覽資料是ASP.NET中的另外一種層次資料。ASP.NET 2.0不僅支援使用ASP.NET中的網站導覽API編程訪問網站地圖資料,還支援使用SiteMapDataSource控制項進行宣告式的資料繫結。當你把TreeView(或Menu)控制項綁定到SiteMapDataSource的時候,網站地圖的Text和Url屬性可以綁定到TreeNode(或MenuItem)。儘管你可以用一個資料繫結集合來建立這種綁定,但是這樣的操作不是必要的。TreeView和 Menu控制項自動地把TreeNode或 MenuItem的Text和NavigateUrl屬性綁定到相關的網站地圖屬性(這是使用SiteMapNode的INavigateUIData介面實現的)。當TreeView和Menu綁定到SiteMapDataSource的時候,它們還有一個特性,會自動地把SelectedNode或SelectedItem屬性設定為網站地圖中的當前節點。

  下面的例子示範了一個綁定到SiteMapDataSource控制項的TreeView。儘管這個例子使用的是資料繫結集合,但是如果你只需要綁定到節點的Text和Url屬性,這樣的操作就是沒必要的。

<asp:SiteMapDataSource ID="SiteMapSource" runat="server"/>
 <asp:TreeView ID="MyTreeView" SkinId="BulletedList3"
 DataSourceId="SiteMapSource" runat="server">
 <Databindings>
  <asp:TreeNodeBinding TextField="Title" NavigateUrlField="Url" />
 </Databindings>
</asp:TreeView>

 綁定到關聯式資料庫

  當關聯式資料庫中的多個表通過外部鍵相關聯的時候,也可以用階層來表現。例如,在產品資料庫中,產品與產品類別關聯,它們就可以用類別和產品之間的層次(1對多)關係來表現。儘管當前的ASP.NET版本沒有包含一個用於把關係資料顯示為階層的控制項,你仍然可以通過編程填充層次的資料繫結控制項(例如TreeView或Menu)的節點/資料項目來實現這種目的。下面的例子顯示了一個用關聯式資料庫填充的TreeView控制項。這個例子利用TreeView的PopulateOnDemand特性,按需求(用戶端上擴充某個TreeNode的時候)來填充子節點。

Sub GetProductCategories(ByVal node As TreeNode)
 Dim categories As CategoryList = WarehouseDB.GetProductCategories()
 Dim c As Category
 For Each c In categories
  Dim newNode As TreeNode = New TreeNode(c.Name, c.Id)
  newNode.SelectAction = TreeNodeSelectAction.Expand
  newNode.PopulateOnDemand = True
  node.ChildNodes.Add(newNode)
 Next
End Sub

Sub GetProductsForCategory(ByVal node As TreeNode)
 Dim categoryId As String = node.Value
 Dim products As ProductList = WarehouseDB.GetProductsForCategory(categoryId)
 Dim p As Product
 For Each p In products
  Dim newNode As TreeNode = New TreeNode(p.Name, p.Id)
  node.ChildNodes.Add(newNode)
 Next
End Sub

Sub PopulateNode(ByVal source As Object, ByVal e As TreeNodeEventArgs)
 Select Case e.Node.Depth
  Case 0
   GetProductCategories(e.Node)
  Case 1
   GetProductsForCategory(e.Node)
 End Select
End Sub

<asp:TreeView ID="TreeView1" OnTreeNodePopulate="PopulateNode" SkinId="Simple" Width="250" ExpandDepth="0" runat="server">
<Nodes>
<asp:TreeNode Text="Inventory" SelectAction="Expand" PopulateOnDemand="true"/>
</Nodes>
</asp:TreeView>



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.