asp.net ListView使用DataBind排序

时间:2011-09-28 16:20:07

标签: asp.net data-binding listview sorting

使用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>

DataBind示例:

<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方法背后的代码进行排序?

谢谢!

3 个答案:

答案 0 :(得分:9)

我解决了我的问题。

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

我必须创建一个视图状态来保存列表视图排序方向,因为由于某种原因,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();
    }
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

因为依赖于排序表达式(你在标记中定义),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