2

我有一个页面(category-list.apsx),它使用Repeater Control 方法在页面上显示xml 详细信息。我使用了此处显示的示例:

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

这很好用,但我希望用户能够使用 CategoryName 的下拉列表来过滤结果。

结果中继器如下所示:

<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>
4

1 回答 1

4

好的,这里要介绍很多,所以我不会对每个部分进行过多的详细介绍。希望这可以为您进一步了解 ASP.NET 中的数据绑定提供一个良好的起点。

我更喜欢在代码隐藏中编写我的代码,而不是<script runat="server">在我的 .aspx 页面内部,所以这就是我的代码在本示例中的位置。但是,在功能上,这里没有区别,如果您愿意,可以选择将此代码放在那个 .aspx 端脚本中。

首先,让我们修复您的Repeater模板。您似乎正在使用表格布局,但模板中没有任何地方是实际<table></table>标签。您需要添加一个<HeaderTemplate>和一个<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>

其次DropDownList,让我们在您想要用于过滤的 aspx 页面上声明一个:

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

这里的AutoPostBack属性意味着您DropDownList将自动回发到服务器并在您的服务器上触发一个SelectedIndexChanged您可以在代码中处理的事件。或者,您可以Button在要触发过滤器时使用 a 来单击。

第三,让我们将您的数据绑定代码分成漂亮、整洁的小方法,这些方法可以更容易地重用。

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

那么我们在这里做了什么?通过分离出这些数据绑定方法,我使它更简洁一些,并允许两个单独的控件更轻松地DataSet在 XML 文件中共享相同的控件。Using允许我使用 LINQ,我觉得它比标准查询或对象IEnumerable好得多。DataTableDataView

DropDownList数据绑定代码中,我选择了单列数据并将其转换为字符串集合。我还呼吁Distinct采取良好的措施,以便删除重复项。我还冒昧地在列表中添加了一个空白项,以便用户可以选择 NO 过滤器并显示所有内容。

您会注意到SelectedIndexChanged事件处理程序中有一些代码可以查看 DropDownList 值是否为空。这不一定是最强大的(如果您的某个项目实际上有一个空白的“CategoryName”并且您想对其进行过滤,则会崩溃),但适用于此示例。另一种方法是ddlCategory.SelectedIndex <> 0检查是否选择了过滤器。

这绝不是对这里发生的一切的完整解释,所以请随时提出问题。但是,这应该可以帮助您获得一个工作示例,您可以扩展该示例以用于未来的开发。

编辑: 此代码要求您已导入System.Collections.Generic命名空间和System.Linq命名空间。在 Visual Studio 2010 中,这可能已经自动为您导入到 Web 应用程序项目中。如果没有,您可以选择将它们直接添加到您的代码文件中,或者在您的 Web 应用程序的Project Properties页面上的References > Imported Namespaces下

于 2012-08-30T15:19:05.743 回答