2012-08-30 82 views
2

我有一個頁面(category-list.apsx),它使用Repeater Control方法在頁面上顯示xml詳細信息。我用這裏顯示的例子:中繼器控制方法的ASP.NET過濾器下拉列表

http://www.w3schools.com/aspnet/aspnet_repeater.asp

這工作得很好,但我希望用戶能夠過濾使用類別名稱下拉的結果。

結果轉發這個樣子的:

<form runat="server"> 
<asp:Repeater id="categories" runat="server"> 

    <ItemTemplate> 
     <tr> 
     <td><%#Container.DataItem("CategoryName")%> </td> 
     <td>&nbsp;</td> 
     <td><%#Container.DataItem("CategoryMonth")%> </td> 
     <td>&nbsp;</td> 
     <td><%#Container.DataItem("CategoryMonthSpend")%> </td> 
     <td>&nbsp;</td> 
     <td><%#Container.DataItem("Amount")%> </td> 
     </tr> 
    </ItemTemplate> 

</asp:Repeater> 
</form> 

的XML是這樣的:

<catalog> 
    <categories> 
    <CategoryName>Category Name1</CategoryName> 
    <CategoryMonth>April 2012</CategoryMonth> 
    <CategoryMonthSpend>£1</CategoryMonthSpend> <Amount>1</Amount>        
    </categories> 
</catalog> 

激活中繼器的腳本可以如下圖所示:

<script runat="server"> 
Public Sub Page_Load() 
    If Not Page.IsPostBack Then 
     Dim cat As String = Request.QueryString("cat") 
     Dim mycategories As DataSet = New DataSet() 
     mycategories.ReadXml(MapPath("XML/" + cat + ".xml")) 
     categories.DataSource = mycategories 
     categories.DataBind() 
    End If 
End Sub 

</script> 
+0

你需要一個'DropDownList'控制開始。你有什麼嘗試?問題是什麼? –

+0

[documentation here](http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.selectedindexchanged.aspx)中的示例可能對您有所幫助。更改'Index_Changed'中的代碼以適當地過濾列表。 –

+0

@Jason您能否將您用來綁定您的'Repeater'的代碼貼出來?另外,請包含您爲'DropDownList'控件定義的標記。 – mclark1129

回答

4

OK ,在這裏可以覆蓋很多,所以我不會對每個部分進行詳細的介紹。希望這會給你一個很好的起點,讓你更好地理解ASP.NET中的Databinding。

我更喜歡在代碼隱藏中編寫我的代碼,而不是在我的.aspx頁面中輸入<script runat="server">,這就是我的代碼在這個例子中的位置。但功能上,這裏沒有區別,如果您願意,您可以選擇將該代碼放入.aspx側腳本中。

第一個,讓我們來修復您的Repeater模板。您似乎正在使用表格佈局,但您的模板中沒有任何地方是實際的<table></table>標記。您需要添加一個和<FooterTemplate>

<asp:Repeater id="categories" runat="server">  
    <HeaderTemplate> 
     <table> 
    </HeaderTemplate> 
    <ItemTemplate> 
     <tr> 
      <td><%#Container.DataItem("CategoryName")%> </td> 
      <td>&nbsp;</td> 
      <td><%#Container.DataItem("CategoryMonth")%> </td> 
      <td>&nbsp;</td> 
      <td><%#Container.DataItem("CategoryMonthSpend")%> </td> 
      <td>&nbsp;</td> 
      <td><%#Container.DataItem("Amount")%> </td> 
      </tr> 
    </ItemTemplate> 
    <FooterTemplate> 
     </table> 
    </FooterTemplate>  
</asp:Repeater> 

,我們宣佈你的aspx頁面上DropDownList你想使用過濾:

<asp:DropDownList ID="ddlCategory" runat="server" AutoPostBack="true" /> 

AutoPostBack屬性在這裏意味着您的DropDownList將自動回發到服務器,並在您的服務器上觸發您可以在代碼中處理的SelectedIndexChanged事件。或者,您可以使用Button在您想要觸發過濾器時點擊。

第三,讓我們分開您的數據綁定代碼到漂亮,整潔的小方法,可以更容易地重用。

Private Function GetXmlDataSet() As IEnumerable(Of DataRow) 

    Dim cat As String = Request.QueryString("cat") 
    Dim mycategories As DataSet = New DataSet() 

    mycategories.ReadXml(MapPath("XML/" + cat + ".xml")) 

    ' I like to use IEnumerable because so that I can use LINQ ' 
    Return mycategories.Tables(0).AsEnumerable() 

End Function 

Private Sub BindRepeater(query As IEnumerable(Of DataRow)) 
    categories.DataSource = query 
    categories.DataBind() 
End Sub 

Private Sub BindDropDownList(query As IEnumerable(Of DataRow)) 

    ddlCategory.DataSource = query.Select(Function(x) x("CategoryName")).Distinct() 
    ddlCategory.DataBind() 

    ' Insert an empty choice into the DropDownList ' 
    ddlCategory.Items.Insert(0, "") 

End Sub 

,讓我們更新您的Page_Load代碼,以便我們可以利用這些方法的優點:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

    If (Not IsPostBack) Then 

     Dim query = GetXmlDataSet() 

     BindDropDownList(query) 
     BindRepeater(query) 

    End If 

End Sub 

最後肯定不是最不重要的,我們爲了創造SelectedIndexChanged事件處理程序觸發此數據集的過濾:

Private Sub ddlCategory_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ddlCategory.SelectedIndexChanged 

    Dim selectedCategory As String = ddlCategory.SelectedValue.ToString() 

    Dim query = GetXmlDataSet() 
    If (Not String.IsNullOrEmpty(selectedCategory)) Then 
     query = GetXmlDataSet().Where(Function(x) x("CategoryName") = selectedCategory) 
    End If 

    BindRepeater(query) 

End Sub 

那麼我們在這裏做了什麼?通過分離出這些數據綁定方法,我使它更簡潔一些,並允許兩個單獨的控件更容易在您的XML文件中共享相同的DataSet。使用IEnumerable允許我使用LINQ,我覺得它比標準查詢DataTableDataView對象要好得多。

DropDownList數據綁定代碼中,我選擇了一列數據並將其轉換爲字符串集合。我也打電話給Distinct,以便重複刪除。我還可以隨意在列表中添加一個空白項目,以便用戶可以選擇NO篩選並顯示所有內容。

您會注意到SelectedIndexChanged事件處理程序中有一小段代碼來查看DropDownList值是否爲空。這不一定是最強大的(如果其中一個項目實際上有一個空白的「CategoryName」,並且您想對其過濾),但會適用於此示例。另一種方法是使用ddlCategory.SelectedIndex <> 0來檢查是否選擇了過濾器。

這絕不是對這裏發生的一切事情的完整解釋,所以請隨時提問。然而,這應該有助於讓你成爲一個可以在未來發展中擴展的實例。

編輯:此代碼要求您已導入System.Collections.Generic命名空間和System.Linq命名空間。在Visual Studio 2010中,這可能已經自動導入到Web應用程序項目中。如果沒有,你可以選擇直接在你的代碼文件或在項目屬性頁面添加它們爲Web應用程序下參考>導入的命名空間

+0

謝謝你的時間邁克!我更新了代碼,並且彈出了以下錯誤:BC32045:'System.Collections.IEnumerable'沒有類型參數,因此不能有類型參數。我猜我已經插入了錯誤的代碼? – Jason

+0

您可能需要導入'System.Collections.Generic'命名空間。 – mclark1129

+0

好的,我已經在頂部添加了代碼<%@ Import Namespace =「System.Collections.Generic」%>並且已經離開了<%@ Import Namespace =「System.Data」%>「。它現在跳到一個新的錯誤:BC30456:'選擇'不是'System.Collections.Generic.IEnumerable(Of System.Data.DataRow)'的成員。和它的行:ddlCategory.DataSource = query.Select(Function(x)x(「CategoryName」))。Distinct()..任何想法? – Jason