ASP.NET2.0中怎么嵌套數(shù)據(jù)控件-創(chuàng)新互聯(lián)

這篇文章將為大家詳細講解有關(guān)ASP.NET 2.0中怎么嵌套數(shù)據(jù)控件,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

在阿克陶等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作 網(wǎng)站設(shè)計制作按需求定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站制作,阿克陶網(wǎng)站建設(shè)費用合理。

第一步: 創(chuàng)建Category列表

當創(chuàng)建一個使用嵌套數(shù)據(jù)控件的頁時,我發(fā)現(xiàn)開始從最外層的控件的設(shè)計,創(chuàng)建和測試開始非常的有幫助,這個時候不用管內(nèi)層嵌套的控件.因此,我們首先實現(xiàn)往頁面里添加一個Repeater來列出category的name和description.

打開DataListRepeaterBasics文件夾里的NestedControls.aspx頁.添加一個Repeater控件,將ID設(shè)為CategoryList..通過它的智能標簽,選擇創(chuàng)建一個新的名為CategoriesDataSource的ObjectDataSource.

ASP.NET 2.0中怎么嵌套數(shù)據(jù)控件
圖 2: 創(chuàng)建一個名為CategoriesDataSource的ObjectDataSource

用CategoriesBLL類的GetCategories方法配置O

ASP.NET 2.0中怎么嵌套數(shù)據(jù)控件
圖3: 用CategoriesBLL類的GetCategories方法配置ObjectDataSource

我們需要切換到源視圖來手動輸入聲明代碼指定Repeater的template內(nèi)容.增加一個帶<h5>的name和<p>的description的ItemTemplate.用<hr>將category分開.在作完這些后,你的頁面代碼里的Repeater和ObjectDataSource聲明語言應(yīng)該和下面差不多:

<asp:Repeater ID="CategoryList" DataSourceID="CategoriesDataSource"
 EnableViewState="False" runat="server">
 <ItemTemplate>
  <h5><%# Eval("CategoryName") %></h5>
  <p><%# Eval("Description") %></p>
 </ItemTemplate>
 <SeparatorTemplate>
  <hr />
 </SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
 OldValuesParameterFormatString="original_{0}"
 SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

圖4 表示現(xiàn)在在瀏覽器里瀏覽這個頁.

ASP.NET 2.0中怎么嵌套數(shù)據(jù)控件
圖 4:列出每個Category的 Name 和Description , 用水平線隔開

第二步: 增加嵌套的Repeater顯示Product

下一步我們的任務(wù)是在CategoryList的ItemTemplate里添加一個Repeater用來顯示屬于各個category下的product.有很多方法可以存取內(nèi)層的Repeater數(shù)據(jù),我們將探討兩種現(xiàn)在我們在CategoryList Repeater的ItemTemplate里創(chuàng)建product Repeater.每個product里將包含name和price我們將下面的標記加到CategoryList的ItemTemplate里:

<asp:Repeater ID="ProductsByCategoryList" EnableViewState="False"
 runat="server">
 <HeaderTemplate>
  <ul>
 </HeaderTemplate>
 <ItemTemplate>
  <li><strong><%# Eval("ProductName") %></strong>
   (<%# Eval("UnitPrice", "{0:C}") %>)</li>
 </ItemTemplate>
 <FooterTemplate>
  </ul>
 </FooterTemplate>
</asp:Repeater>

第三步: 將各Category下的Product綁定到 ProductsByCategoryList Repeater

如果現(xiàn)在你瀏覽這個頁,你會看到象圖4一樣的頁面,因為我們還沒有在Repeater里綁定任何數(shù)據(jù).有幾種方法可以將合適的product記錄綁定到Repeater里,其中一些會比較有效.現(xiàn)在主要的任務(wù)是為指定category取到合適的product.可以通過在ItemTemplate里語法聲明ObjectDataSource或者直接在后臺代碼編程來將數(shù)據(jù)綁定到內(nèi)層的Repeater.

通過ObjectDataSource和ItemDataBound來獲取數(shù)據(jù)

這里我們還是用ObjectDataSource來實現(xiàn).ProductsBLL類的GetProductsByCategoryID(Category)
方法可以返回特定CategoryID的products信息.因此,我們將在CategoryList Repeater的ItemTemplate里新建一個ObjectDataSource,并用這個方法配置它.不幸的,Repeater不允許通過設(shè)計視圖來修改template,因此我們需要手動添加將聲明語法.見下面的代碼:

<h5><%# Eval("CategoryName") %></h5>
<p><%# Eval("Description") %></p>
<asp:Repeater ID="ProductsByCategoryList" EnableViewState="False"
  DataSourceID="ProductsByCategoryDataSource" runat="server">
 <HeaderTemplate>
  <ul>
 </HeaderTemplate>
 <ItemTemplate>
  <li><strong><%# Eval("ProductName") %></strong> -
    sold as <%# Eval("QuantityPerUnit") %> at
    <%# Eval("UnitPrice", "{0:C}") %></li>
 </ItemTemplate>
 <FooterTemplate>
  </ul>
 </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsByCategoryDataSource" runat="server"
   SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
 <SelectParameters>
  <asp:Parameter Name="CategoryID" Type="Int32" />
 </SelectParameters>
</asp:ObjectDataSource>

當使用ObjectDataSource方法時我們需要設(shè)置ProductsByCategoryList Repeater的DataSourceID為ObjectDataSource(ProductsByCategoryDataSource).注意ObjectDataSource有一個<asp:Parameter>來指定傳給GetProductsByCategoryID(categoryID)的categoryID.但是我們怎么來指定這個值呢?我們可以設(shè)置DefaultValue屬性為<asp:Parameter>,見下面的代碼:

<asp:Parameter Name="CategoryID" Type="Int32"
  DefaultValue='<%# Eval("CategoryID")' />

不幸的,數(shù)據(jù)綁定語法只能用在有DataBinding事件的控件里.Parameter類沒有這樣的事件,因此這樣使用會出錯.我們需要為CategoryList Repeater的ItemDataBound創(chuàng)建一個事件處理來設(shè)置這個值.每個item綁定到Repeater時激發(fā)ItemDataBound事件.因此每次外層的Repeater激發(fā)這個時間時,我們可以將當前的CaegoryID的值傳給ProductsByCategoryDataSource ObjectDataSource的CategoryID參數(shù).下面的代碼是為CategoryList Repeater的ItemDataBound創(chuàng)建一個event handler:

protected void CategoryList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
 if (e.Item.ItemType == ListItemType.AlternatingItem ||
  e.Item.ItemType == ListItemType.Item)
 {
  // Reference the CategoriesRow object being bound to this RepeaterItem
  Northwind.CategoriesRow category =
   (Northwind.CategoriesRow)((System.Data.DataRowView)e.Item.DataItem).Row;
  // Reference the ProductsByCategoryDataSource ObjectDataSource
  ObjectDataSource ProductsByCategoryDataSource =
   (ObjectDataSource)e.Item.FindControl("ProductsByCategoryDataSource");
  // Set the CategoryID Parameter value
  ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
   category.CategoryID.ToString();
 }
}

這個event handler首先保證我們操作的是data item而不是header,footer或separator item.然后,引用剛剛綁定到當前RepeaterItem的CategoriesRow實例.最后,引用在ItemTemplate里的ObjectDataSource并將當前RepeaterItem的CategoryID傳給CategoryID參數(shù).

在這個event handler里,每個RepeaterItem里的ProductsByCategoryList Repeater都綁定到RepeaterItem的category里的product.見圖5.

ASP.NET 2.0中怎么嵌套數(shù)據(jù)控件
圖 5: 外層的Repeater 列出每個Category; 內(nèi)層的Repeater 列出屬于Category的Products

直接編程來獲取Category 下的Products

除了使用ObjectDataSource來獲取當前category下的proudct外,我們還可以在ASP.NET頁的code-behind里(或App_Code文件夾里或一個單獨的類項目里)來創(chuàng)建一個根據(jù)傳入的CategoryID返回合適的product集的方法.假設(shè)在ASP.NET頁的code-behind里有一個名為GetProductsInCategory(categoryID)方法.我們可以使用這個方法來將當前category下的product綁定到內(nèi)層的Repeater.見下面的代碼:


<asp:Repeater runat="server" ID="ProductsByCategoryList" EnableViewState="False"
  DataSource='<%# GetProductsInCategory((int)(Eval("CategoryID"))) %>'>
 ...
</asp:Repeater>

Repeater的DataSource屬性通過綁定語法來指定它的數(shù)據(jù)是通過GetProductsInCategory(categoryID)得到.由于Eval("CategryID")返回的是Object類型,我們在它傳入GetProductsInCategory(categoryID)前將它轉(zhuǎn)化成Integer.注意這里的CategoryID是通過外層Repeater(CategoryList)的CategoryID(已經(jīng)綁定到Categories table)獲取的.因此它不可能是一個NULL值.所以我們在綁定前沒有檢查.

我們現(xiàn)在需要創(chuàng)建GetProductsInCategory(categoryID)方法.在這里簡單使用ProductsBLL類的GetProductsByCategoryID(categoryID)方法返回的ProductsDataTable就可以了.我們在NestedControls.aspx頁的code-behind里創(chuàng)建GetProductsInCategory(categoryID).見下面的代碼:

protected Northwind.ProductsDataTable GetProductsInCategory(int categoryID)
{
 // Create an instance of the ProductsBLL class
 ProductsBLL productAPI = new ProductsBLL();
 // Return the products in the category
 return productAPI.GetProductsByCategoryID(categoryID);
}

這個方法僅僅是創(chuàng)建一個ProductsBLL實例然后返回GetProductsByCategoryID(categoryID)方法的返回值.注意這個方法必須標記為Public或Protected.如果標記為Private,ASP.NET頁的聲明標記里將不能調(diào)用它.
做完以上操作后,在瀏覽器里瀏覽頁面.頁面看起來應(yīng)該和使用ObjectDataSource 和ItemDataBound event handler方法差不多(圖5).

注意:在ASP.NET頁的code-behind里創(chuàng)建GetProductsInCategory(categoryID)方法好象只是一個形式,畢竟這個方法只是調(diào)用BLL里的方法.為什么不直接在內(nèi)層Repeater里的綁定語法里直接調(diào)用這個方法.比如:
DataSource='<%#ProductsBLL.GetProductsByCategoryID(CType(Eval("CategoryID"),Integer))%>')
雖然這個聲明是不起作用的(因為GetProductsByCategoryID(categoryID)方法是一個實例方法),你可以修改ProductsBLL來包含一個這樣的靜態(tài)方法.這樣的修改可以滿足ASP.NET頁的GetProductsInCategory(categoryID)方法的需要,但是寫在code-behind里可以更靈活的獲取數(shù)據(jù),我們在后面會看到這點.

獲取所有的Product 信息

前面兩個方法我們通過調(diào)用ProductsBLL類的GetProductsByCategoryID(categoryID)方法來獲取當前category的product(第一種通過ObjectDataSource,第二種通過GetProductsInCategory(categoryID)).每次方法被調(diào)用時,BLL調(diào)用DAL,DAL通過SQL查詢數(shù)據(jù)庫,返回特定的記錄.

如果有N個category,這個方法會訪問數(shù)據(jù)庫N+1次— 一次返回所有的category,N次返回特定category下的product.然而我們可以通過訪問數(shù)據(jù)庫兩次來獲取所有需要的數(shù)據(jù)— 一次返回所有的category,一次返回所有的product.一旦我們得到所有的product,我們可以根據(jù)CategoryID來過濾,然后再綁定.

我們只需要稍微修改ASP.NET頁的code-behind里的GetProductsInCategory(categoryID)方法來實現(xiàn)這個功能.我們首先來返回所有的product,然后根據(jù)傳入的CategoryID里過濾.

private Northwind.ProductsDataTable allProducts = null;
protected Northwind.ProductsDataTable GetProductsInCategory(int categoryID)
{
 // First, see if we've yet to have accessed all of the product information
 if (allProducts == null)
 {
  ProductsBLL productAPI = new ProductsBLL();
  allProducts = productAPI.GetProducts();
 }
 // Return the filtered view
 allProducts.DefaultView.RowFilter = "CategoryID = " + categoryID;
 return allProducts;
}

注意allProducts變量.它在第一次調(diào)用GetProductsInCategory(categoryID)時返回所有product信息.確定allProducts對象被創(chuàng)建后,在根據(jù)CategoryID來對DataTable過濾.這個方法將訪問數(shù)據(jù)庫的次數(shù)從N+1減少到2次.
這個改進沒有修改頁面的聲明語言.僅僅只是減少了數(shù)據(jù)庫的訪問次數(shù).

注意:可能想當然的覺得減少了數(shù)據(jù)庫訪問次數(shù)會提高性能.但是這個不一定.如果你有大量的categoryID為NULL的product,這樣使用GetProducts方法返回的product有一部分不會被顯示.而且如果你只需要顯示一部分category的proudct(分頁時就是這樣),而返回所有的product,這樣對資源也是一種浪費.通常對兩種技術(shù)進行性能分析,正確的方法是設(shè)置程序常見的場景來進行壓力測試.

關(guān)于ASP.NET 2.0中怎么嵌套數(shù)據(jù)控件就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

新聞標題:ASP.NET2.0中怎么嵌套數(shù)據(jù)控件-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://muchs.cn/article2/dphpic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計公司、建站公司企業(yè)網(wǎng)站制作、標簽優(yōu)化、微信公眾號、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作