2012-08-30 79 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