【问题标题】:asp.net ListView Sorting using DataBind使用 DataBind 的 asp.net ListView 排序
【发布时间】:2011-09-28 16:20:06
【问题描述】:

使用 LayoutTemplate 中的列标题对列表视图进行排序

我可以使用 asp:SqlDataSource 对基本列表视图进行排序,并通过将其指向 asp:SqlDataSource ID 来设置列表视图属性 DataSourceID。我在不使用 asp:SqlDataSource 并且仅使用后面代码中的 DataBinding 进行排序时遇到问题。

SqlDataSource 示例:

<asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource" runat="server">
    <LayoutTemplate>
        <table width="640px" runat="server">
            <tr class="header" align="center" runat="server">
                <td>
                    <asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
    </LayoutTemplate>
    ....
</asp:ListView>

<asp:SqlDataSource ID="ContactsDataSource" runat="server" 
    ConnectionString="<%$ ConnectionStrings:MainConnString %>"
    SelectCommand="SELECT * FROM TableName">
</asp:SqlDataSource>

数据绑定示例:

<asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource" runat="server">
    <LayoutTemplate>
        <table width="640px" runat="server">
            <tr class="header" align="center" runat="server">
                <td>
                    <asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
    </LayoutTemplate>
    ....
</asp:ListView>

protected void Page_Load(object sender, EventArgs e)
{
    String SQL = "SELECT * FROM Customer";
    SqlDataAdapter da= new SqlDataAdapter(SQL, ConnStr);
    DataSet ds = new DataSet();
    da.Fill(ds);

    ContactsListView.DataSource = ds.Tables[0];
    ContactsListView.DataBind();
}

两个代码示例都填充列表视图,但第二个示例数据绑定不适用于排序。对于第一个示例,排序仅适用于 LayoutTemplate 中添加的 asp:LinkBut​​ton 添加 CommandName="sort" 并设置 CommandArugment="ColumnName",但不适用于第二个示例。

谁能解释一下为什么以及如何使用 DataBind 方法背后的代码进行排序?

谢谢!

【问题讨论】:

  • 您的代码中没有处理排序的内容 - 您尝试了什么导致了问题?您可以在 SQL 查询中添加一个 ORDER BY 子句,或者添加一些代码隐藏来对数据绑定进行排序——这取决于您想要实现的目标;让我们知道。
  • 这两个示例都填充了列表视图,但对于第一个示例,当单击列标题时,我不必添加任何其他代码来使排序工作。
  • 我想出了我的解决方案,并将在今晚晚些时候发布。我的声誉不允许我在 8 小时后发布。基本上如以下答案所示,我必须创建自己的 OnSort 事件处理程序,将数据库重新查询到 DataTable 中,对 DataTable 进行排序,然后将其绑定回 ListView。如果有无需再次调用数据库的方法,请告诉我。

标签: asp.net data-binding listview sorting


【解决方案1】:

我解决了我的问题。

我添加了一个事件来处理排序。该事件获取命令名称(数据列)并将其和排序方向传递给一个函数,该函数将对数据库进行另一次调用,对返回的结果进行排序并重新绑定到列表视图。

我必须创建一个视图状态来保存列表视图排序方向,因为出于某种原因,onsorting 事件处理程序一直说排序方向是升序。

前端

<asp:ListView ID="ContactsListView" OnSorting="ContactsListView_Sorting" runat="server">
    <LayoutTemplate>
        <table width="640px" runat="server">
            <tr class="header" align="center" runat="server">
                <td>
                    <asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
    </LayoutTemplate>
    ....
</asp:ListView>

后端

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        BindContacts(string.Empty);
    }
}

protected SortDirection ListViewSortDirection
{
    get
    {
        if (ViewState["sortDirection"] == null)
            ViewState["sortDirection"] = SortDirection.Ascending;
        return (SortDirection)ViewState["sortDirection"];
    }
    set { ViewState["sortDirection"] = value; }
}

protected void ContactsListView_Sorting(Object sender, ListViewSortEventArgs e)
{
    BindContacts(e.SortExpression + " " + ListViewSortDirection.ToString());

    // Check the sort direction to set the image URL accordingly.
    string imgUrl;
    if (ListViewSortDirection == SortDirection.Ascending)
        ListViewSortDirection = SortDirection.Descending;
    else
        ListViewSortDirection = SortDirection.Ascending;
}

private void BindContacts(string sortExpression)
{
    sortExpression = sortExpression.Replace("Ascending", "ASC");
    sortExpression = sortExpression.Replace("Descending", "DESC");
    using (SqlConnection conn = new SqlConnection(_connStr))
    {
        conn.Open();
        using (SqlDataAdapter dAd = new SqlDataAdapter("SELECT * FROM Customer", conn))
        {
            DataTable dTable = new DataTable();
            dAd.Fill(dTable);
            // Sort now
            dTable.DefaultView.Sort = sortExpression;
            // Bind data now
            ContactsListView.DataSource = dTable;
            ContactsListView.DataBind();
        }
        conn.Close();
    }
}

【讨论】:

    【解决方案2】:

    我猜你可以尝试为ListViewSorting 事件添加一个处理程序。在那里,您将获得事件参数中的排序列和排序顺序。这可以很容易地用于构建特定查询并将其绑定到列表。

    【讨论】:

    • 他们有什么例子可以让我开始吗?我知道你所说的事件,但我从未使用过它。
    【解决方案3】:

    因为取决于排序表达式(您在标记中定义)SqlDataSource 很可能会做一些类似的事情(我不确定这究竟是什么确实)在幕后为您服务:

    Expression<Func<DataRow,object>> myExpression = row => row["SortExpressionYouDefinedForTheColumn"];
    IEnumerable<DataRow> ex = ds.Tables[0].AsEnumerable().OrderBy(myExpression.Compile());
    

    或者SqlDataSource 可能正在使用DataViewDataTable 进行排序。

    SqlDataSource 可以这样做,因为默认情况下它使用 DataSet 来存储结果集 (or so says the documentation):

    数据检索模式标识 SqlDataSource 控件如何从基础数据库中检索数据。

    当 DataSourceMode 属性设置为 DataSet 值时,数据为 加载到 DataSet 对象并存储在服务器的内存中。这个 启用用户界面控件(例如 GridView)的场景, 提供排序、过滤和分页功能..

    由于您选择手动绑定到 DataSet,您需要自己做“魔术”;换句话说,您处理 OnSort 命令,获取排序表达式,再次获取您的数据源(无论如何,从 Session 或通过再次调用数据库)并进行类似于上面显示的行的排序并重新绑定到您的 Gridview .

    【讨论】:

      猜你喜欢
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多