C# 如果使用自定义数据源,如何对 ASP.NET GridView 中的列进行排序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/138412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to sort columns in an ASP.NET GridView if using a custom DataSource?
提问by Ben L
I can't get my GridView to enable a user to sort a column of data when I'm using a custom SqlDataSource.
当我使用自定义 SqlDataSource 时,我无法让我的 GridView 使用户能够对一列数据进行排序。
I have a GridView in which the code in the ASP reference to it in the HTML is minimal:
我有一个 GridView,其中 HTML 中 ASP 引用中的代码最少:
<asp:GridView id="grid" runat="server" AutoGenerateColumns="False" AllowSorting="True">
</asp:GridView>
In the code-behind I attach a dynamically-created SqlDataSource (the columns it contains are not always the same so the SQL used to create it is constructed at runtime). For example:
在代码隐藏中,我附加了一个动态创建的 SqlDataSource(它包含的列并不总是相同的,因此用于创建它的 SQL 是在运行时构造的)。例如:
I set up the columns...
我设置了列...
BoundField column = new BoundField();
column.DataField = columnName;
column.HeaderText = "Heading";
column.SortExpression = columnName;
grid.Columns.Add(column);
the data source...
数据源...
SqlDataSource dataSource = new SqlDataSource(
"System.Data.SqlClient",
connectionString,
generatedSelectCommand);
then the gridview...
然后网格视图...
grid.DataSource = dataSource;
grid.DataKeyNames = mylistOfKeys;
grid.DataBind();
At the moment nothing happens when a user clicks on a column heading when I'd expect it to sort the column data. Anyone any ideas what I'm missing?
目前,当我希望它对列数据进行排序时,当用户单击列标题时,没有任何反应。有人知道我缺少什么吗?
If there's a nicer way of doing this that would be helpful too as this looks messy to me!
如果有更好的方法来做到这一点也会很有帮助,因为这对我来说看起来很混乱!
采纳答案by Keith
First you need to add an event:
首先你需要添加一个事件:
<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ...
Then that event looks like:
然后那个事件看起来像:
protected void gvName_Sorting( object sender, GridViewSortEventArgs e )
{
...
//rebind gridview
}
You basically have to get your data again.
您基本上必须再次获取数据。
You're right that it looks messy and there is a better way: ASP.Net MVC
你说得对,它看起来很乱,有一个更好的方法:ASP.Net MVC
Unfortunately that's a drastically different page model.
不幸的是,这是一个完全不同的页面模型。
回答by Biri
I'm not sure about this one, but if you use a standard SqlDataSource and you click on a field to sort according to that field, the SqlDataSource is populated again with the data and it is rebound to the grid. So the sorting does not happen on the client side and also can be done only when the selectmethod of the SQLDataSource is not DataReader.
我不确定这个,但是如果您使用标准的 SqlDataSource 并单击一个字段以根据该字段进行排序,SqlDataSource 将再次填充数据并将其反弹到网格。所以排序不会发生在客户端,也只能在SQLDataSource 的selectmethod 不是DataReader 时进行。
When handling the sorting event, do you recreate the SqlDataSource and rebound it to the GridView? Can you put the sort field and direction to the generatedSelectCommand, which you use? Or put it to the SortParameterName property of the SQLDataSource?
处理排序事件时,是否重新创建了SqlDataSource 并重新绑定到GridView?您可以将排序字段和方向放在您使用的生成的SelectCommand 中吗?或者把它放到 SQLDataSource 的 SortParameterName 属性中?
I'm absolutely sure that you have to rebound the SqlDataSource to the grid, and since you create it on the fly, you have to populate it again.
我绝对确定您必须将 SqlDataSource 重新绑定到网格,并且由于您是动态创建的,因此您必须再次填充它。
回答by Martin
Better late than never?
迟到总比不到好?
Some addition for Keith's suggestion which is basically the right one.
基思建议的一些补充,这基本上是正确的。
Truth is, that you have to deal with sorting on gridView_Sorting event. There is no need to DataBind() the GridView earlier, for example in Page_Load event. There you should only call the GridView.Sort() method instead of .DataBind(). Here is how it goes:
事实是,您必须处理对 gridView_Sorting 事件的排序。不需要 DataBind() 之前的 GridView,例如在 Page_Load 事件中。在那里你应该只调用 GridView.Sort() 方法而不是 .DataBind()。这是它的过程:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Me.gridView.Sort(Request.QueryString("sortExpression"), Request.QueryString("sortDirection"))
End If
End Sub
Next let's have a look on gridView_Sorting event.
接下来让我们看看 gridView_Sorting 事件。
There you have to push the datasource to the right sorting. GridView itself does not handle that (in this case at least).
在那里,您必须将数据源推送到正确的排序。GridView 本身不处理(至少在这种情况下)。
Protected Sub gridView_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gridView.Sorting
If IsPostBack Then
e.Cancel = True
Dim sortDir As SortDirection = SortDirection.Ascending
If e.SortExpression = Me.Q_SortExpression And Me.Q_SortDirection = SortDirection.Ascending Then
sortDir = SortDirection.Descending
End If
RedirectMe(e.SortExpression, sortDir)
Else
Dim sortExpr As String = e.SortExpression + " " + IIf(e.SortDirection = SortDirection.Ascending, "ASC", "DESC")
Dim dv As System.Data.DataView = Me.dsrcView.Select(New DataSourceSelectArguments(sortExpr))
Me.gridView.DataSource = dv
Me.gridView.DataBind()
End If
End Sub
No need to code any sorting functionality in data source like passing sort parameters to stored procedure. All sorting takes place in the above pieces of code.
无需在数据源中编写任何排序功能,例如将排序参数传递给存储过程。所有排序都在上述代码段中进行。
Moreover, it's good to have the gridView.EnableViewState switched to False which causes the page to be much lighter for the network traffic and for the browser as well. Can do that as the grid is entirely recreated whenever the page is post back.
此外,最好将 gridView.EnableViewState 切换为 False,这会导致页面对于网络流量和浏览器来说更轻。可以这样做,因为每当页面回发时都会完全重新创建网格。
Have a nice day!
祝你今天过得愉快!
Martin
马丁
回答by Mike
You could also just reassign the datasource.SelectCommand before the DataBind() call in the Sorting handler. Something like this:
您也可以在排序处理程序中的 DataBind() 调用之前重新分配 datasource.SelectCommand 。像这样的东西:
protected void gvItems_Sorting(object sender, GridViewSortEventArgs e)
{
GridView gv = (GridView)sender;
SqlDataSource ds = (SqlDataSource)gv.DataSource;
ds.SelectCommand = ds.SelectCommand + " order by "
+ e.SortExpression + " " + GetSortDirection(e.SortDirection);
gvItems.DataSource = ds;
gvItems.DataBind();
}
string GetSortDirection(string sSortDirCmd)
{
string sSortDir;
if ((SortDirection.Ascending == sSortDirCmd))
{
sSortDir = "asc";
}
else
{
sSortDir = "desc";
}
return sSortDir;
}
I hope this help. Let me know if you need extra help to implement it.
我希望这会有所帮助。如果您需要额外的帮助来实施它,请告诉我。
Enjoy!
享受!