Reputation: 8170
Is there a simple ".Net" way to do hierarchical sorting
Table...
A|B|C
-----
1|2|5
2|8|4
2|4|3
3|7|2
4|4|1
clicking on A, then B would get you..
A|B|C
-----
1|2|5
2|4|3
2|8|4
3|7|2
4|4|1
The change being that I'm sorting (B) in context of (A) and so forth.
Obviously this could be managed in the datasource, but was wondering if someone has a elegant and scalable solution.. thanks.
Upvotes: 1
Views: 4888
Reputation: 21
In order to get an ASP.NET GridView to correctly sort when multiple columns are listed in a BoundField's Sort specification, you need to bind the grid's OnSorting event to this function:
protected void gridViewSorting(object sender, GridViewSortEventArgs e)
{
//
// This odd function permits GridView objects to sort on multiple columns
// Without this function, a GridView object does not sort correctly when multiple
// columns are named in its sort specification.
//
if (!(sender is GridView))
{
return;
}
if (!e.SortExpression.Contains(','))
{
return;
}
GridView gv = sender as GridView;
//
// Find the column that is to become the basis of the sort
//
foreach (DataControlField dc in gv.Columns)
{
String fieldSortExprClean = dc.SortExpression.Replace(" DESC", "");
fieldSortExprClean = fieldSortExprClean.Replace(" ASC", "");
String eventSortExprClean = e.SortExpression.Replace(" DESC", "");
eventSortExprClean = eventSortExprClean.Replace(" ASC", "");
if (fieldSortExprClean == eventSortExprClean)
{
if (e.SortDirection == SortDirection.Ascending)
{
dc.SortExpression = fieldSortExprClean.Replace(",", " ASC,");
e.SortExpression = fieldSortExprClean.Replace(",", " ASC,");
}
else
{
dc.SortExpression = fieldSortExprClean.Replace(",", " DESC,");
e.SortExpression = fieldSortExprClean.Replace(",", " DESC,");
}
}
}
}
Upvotes: 2
Reputation: 48623
If you're asking about doing it in conjunction with paging, there's no simple and scalable solution. In fact, that is kind of a holy grail of business application web development. See, for example, the StackOverflow question Dynamic Sorting within SQL Stored Procedures, which concerns the same thing. After all, if we had dynamic sorting on our database servers, we would only have to code the mechanism for managing the user's sort choices.
You really only have three options for multi-column sorts:
Do it in the client, letting your data container do the heavy lifting (when you're using a data container that has this functionality built in, like System.Data.DataView
).
Write your own algorithm and sort the data yourself before binding.
Do it at the database server via one of the solutions discussed in the link above.
Neither of the client-side solutions are really scalable since they involve pulling and delivering all your data when you may only need a subset.
Upvotes: 2
Reputation: 25280
ASPX page
<asp:GridView id="MyGridView" runat="server" AllowSorting="true" OnSorting="MyGridView_OnSorting">
<asp:BoundField DataField="ColumnA" SortExpression="A" />
<asp:BoundField DataField="ColumnB" SortExpression="B" />
<asp:BoundField DataField="ColumnC" SortExpression="C" />
</asp:GridView>
Code Behind
protected void MyGridView_OnSorting(object sender, GridViewSortEventArgs e)
{
List<MyEntity> data = MyBLL.GetDataSource();
data.Sort(delegate(MyEntity x, MyEntity y) {
switch(e.SortExpression)
{
case "ColumnA":
return String.Compare(x.ColumnA, y.ColumnA);
break;
case "ColumnB":
return String.Compare(x.ColumnB, y.ColumnB);
break;
case "ColumnC":
return String.Compare(x.ColumnC, y.ColumnC);
break;
}
}
);
MyGridView.DataSource = data;
MyGridView.DataBind();
}
Upvotes: 0