使用数据绑定的asp.net ListView排序

使用数据绑定的asp.net ListView排序,asp.net,data-binding,listview,sorting,Asp.net,Data Binding,Listview,Sorting,使用LayoutTemplate中的列标题对列表视图进行排序 我能够使用asp:SqlDataSource对基本列表视图进行排序,并通过将列表视图属性DataSourceID指向asp:SqlDataSource ID来设置它。在不使用asp:SqlDataSource而只是从后面的代码进行数据绑定时,我在排序时遇到问题 SqlDataSource示例: <asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource

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

我能够使用asp:SqlDataSource对基本列表视图进行排序,并通过将列表视图属性DataSourceID指向asp:SqlDataSource ID来设置它。在不使用asp:SqlDataSource而只是从后面的代码进行数据绑定时,我在排序时遇到问题

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();
}

....
数据绑定示例:

<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();
}

....
受保护的无效页面加载(对象发送方、事件参数e)
{
String SQL=“选择*来自客户”;
SqlDataAdapter da=新的SqlDataAdapter(SQL,ConnStr);
数据集ds=新数据集();
da.填充(ds);
ContactsListView.DataSource=ds.Tables[0];
ContactsListView.DataBind();
}
两个代码示例都填充列表视图,但第二个示例数据绑定不适用于排序。在第一个示例中,排序仅与LayoutTemplate中添加的asp:LinkButton一起工作,添加CommandName=“sort”并设置commandArumment=“ColumnName”,但在第二个示例中不起作用

有人能解释一下为什么以及如何使用代码隐藏数据绑定方法进行排序吗


谢谢

我想您可以尝试为
ListView
排序事件添加一个处理程序。在事件参数中为您提供了排序列和排序顺序。这可以很容易地用于构建特定的查询并将其绑定到列表。

因为根据排序表达式(您在标记中定义的),SqlDataSource很可能会在幕后为您执行类似的操作(我不确定它到底是这样做的):

Expression<Func<DataRow,object>> myExpression = row => row["SortExpressionYouDefinedForTheColumn"];
IEnumerable<DataRow> ex = ds.Tables[0].AsEnumerable().OrderBy(myExpression.Compile());
Expression myExpression=row=>row[“SortExpressionYouDefinedForTheColumn”];
IEnumerable ex=ds.Tables[0].AsEnumerable().OrderBy(myExpression.Compile());
或者
SqlDataSource
可能正在使用
DataView
DataTable
进行排序

SqlDataSource可以这样做,因为默认情况下它使用数据集存储结果集():

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

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

由于您选择手动绑定到数据集,因此需要自己执行“魔术”;换句话说,您可以处理OnSort命令,获取排序表达式,再次获取数据源(无论您如何操作,从会话还是再次调用数据库),并按照上面显示的行进行排序,然后重新绑定到Gridview。

我解决了我的问题

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

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

您的代码中没有处理排序的内容-您尝试了什么导致了问题?您可以在SQL查询中添加一个
ORDER BY
子句,或者添加一些代码来根据数据绑定对其进行排序—这取决于您想要实现什么;让我们知道。这两个示例都填充了listview,但是对于第一个示例,当单击列标题时,我不必添加任何额外的代码来进行排序。我找到了我的解决方案,并将在今晚晚些时候发布。我的名声不允许我在8小时后发布。基本上正如下面的答案所示,我必须创建自己的OnSort事件处理程序,将数据库重新查询到DataTable中,对DataTable进行排序,然后将其绑定回ListView。如果有一种不用再打电话到数据库就可以去度假的方法,请让我知道。他们有什么例子可以让我开始吗?我知道你正在谈论的事件,但我从未使用过它。