Hi,
I have asked this question in the user forum with no luck!:
http://community.devexpress.com/forums/t/63171.aspx
And I have looked at issues that other users have, for example:
http://www.devexpress.com/Support/Center/p/Q99212.aspx?searchtext=sort&tid=4b2d6f97-c4ae-48fc-87f6-8c5da6541e40&pid=22713479-a995-45d4-9ed4-72ffa096d83d
http://www.devexpress.com/Support/Center/p/Q97780.aspx?searchtext=sort&tid=4b2d6f97-c4ae-48fc-87f6-8c5da6541e40&pid=22713479-a995-45d4-9ed4-72ffa096d83d
I'm not the only one with sorting problems!:
http://www.devexpress.com/Support/Center/SearchResults.aspx?searchtext=sorting&tid=4b2d6f97-c4ae-48fc-87f6-8c5da6541e40&pid=22713479-a995-45d4-9ed4-72ffa096d83d
Is it not possible to make a simle sort in database with your grid???
Could you please, please add sorting events in future releases like MS have!!!
The closest solution I have reached is in one of links above:
- Turn off callbacks: EnableCallBacks="False"
- In postback event, loop through the columns:
if (IsPostBack)
{
GridViewDataColumn dataColumn = null;
int i = 0;
string columnName = String.Empty;
while (i < gvUser.Columns.Count)
{
dataColumn = (GridViewDataColumn)gvUser.Columns[i];
if (dataColumn == null)
{
i += 1;
continue;
}
if (dataColumn.SortOrder != DevExpress.Data.ColumnSortOrder.None)
{
columnName = dataColumn.FieldName;
break;
}
i += 1;
}
Response.Write(columnName);
}
The problem with this code is I have to click twice on the header to get the correct sort name.
Is this the best solution? And do you know why I have to click twice to get the correct name?
Hi Matthias,
The ASPxGridView provides several ways for implementing db server based data sorting:
I will try to explain you why we require a developer to support the IListServer interface, and cannot rely on a sorted data list.
The ASPxGridView provides many more features than the standard GridView - it allows sorting, grouping and filtering data, calculating group and total summaries. The default ASPxGridView does not support all the features starting from grouping in my list. So, even if we would provide an event to use the data, sorted on a db server, we should also calculate total and group summaries, and build groups. I.e. we'd still need to work with the whole bunch of data … which isn't efficient.
So, we've created a special IListServer interface. If your data source class implements it, the ASPxGridView will be able to work with it in server mode, and as a result, propagate all calculations at the data source level.
If you wish to support only sorting, you may use the approach shown in the following tutorial:
Bind a grid to a ObjectDataSource with EnablePaging project.
I know that Mehul suggested that you look at this article. So, If you do not mind, I will answer you here:
protected IEnumerable ExecuteViewSelect(DataSourceSelectArguments ds, bool applySorting) { if(applySorting && sortInfo != null && sortInfo.Count > 0) { ds.SortExpression = GetSortExpression(sortInfo); } return DataSourceView.Select(ds); }
Now, let's return to your original question in this thread. If EnableCallbacks = false, you may use the following code to obtain the list of sorted columns:
System.Collections.ObjectModel.ReadOnlyCollection<GridViewDataColumn> sortedColumns = ASPxGridView1.GetSortedColumns();
and this code works fine in the Page_Load event. In any case, I recommend that you use the approaches suggested above.
Thanks,
Plato
Hi Plato,
First:
Excellent answer! Very detailed. :)
Second:
I understand that your grid have many more features then MS so you can't use the same kind of events.
But in this case I don't need any other features then sorting and paging. All others are set to false.
And because of that, and if I had built a gridview I would start from the MS grid (which everybody knows), with same features and events and so on. After that I would start to add extra features. And if some feature conflicts with a event the feature should just ignore it.
I think that would have been more user friendly! And easier to learn.
But that is just my opinion! :)
Three:
I tried the variant with getting the columns in pageload but I still have the problem that I need to click 2 times on the header.
For example: If I have 2 columns, FirstName and LastName and if I click on LastName it still says FirstName until I click on LastName again.
My test code:
aspx ------------------------------------------------------------
<dxwgv:ASPxGridView ID="gvUser"
ClientInstanceName="gvUser"
runat="server"
Width="100%"
AutoGenerateColumns="False"
EnableCallBacks="False">
<SettingsPager Visible="False">
</SettingsPager>
<Columns>
<dxwgv:GridViewDataTextColumn Caption="Förnamn" Name="FirstName" FieldName="Profile.FirstName" VisibleIndex="0">
</dxwgv:GridViewDataTextColumn>
<dxwgv:GridViewDataTextColumn Caption="Efternamn" Name="LastName" FieldName="Profile.LastName" VisibleIndex="1">
</dxwgv:GridViewDataTextColumn>
<dxwgv:GridViewDataTextColumn Caption="Användarnamn" Name="UserName" FieldName="UserName" VisibleIndex="2">
</dxwgv:GridViewDataTextColumn>
</Columns>
</dxwgv:ASPxGridView>
cb ---------------------------------------------------
protected void Page_Load(object sender, EventArgs e)
{
System.Collections.ObjectModel.ReadOnlyCollection<GridViewDataColumn> sortedColumns = gvUser.GetSortedColumns();
BindGrid("FirstName", true);
foreach (GridViewDataColumn g in sortedColumns)
Response.Write(g.Name + g.SortOrder.ToString() + "<br />");
}
private void BindGrid(string sortColumn, bool sortOrder)
{
//IList<Swh.Ih7.Entities.User> users = UserDao.GetObjects(new Order(sortColumn, sortOrder), skip, take, out recordCount);
IList<Swh.Wb8.Entities.User> users = UserDao.GetObjects();
gvUser.DataSource = users;
gvUser.DataBind();
}
-----------------------------------------------
I have also tried to bind before getting the columns but with same result.
Do you know what could be wrong?
And the grid is still sorting clientside when I click on the headers. How do I turn this off? I only want to sort serverside.
Four:
Do you have any documentation and examples about server mode?
I would really like to read more on how to implement NHibernate with your grid.
Regards
Mattias
Hi Matthias,
First, Thanks :-)
2) Sorry, I do not agree with you. If we provide features, they should be available in any possible mode.
3) You are right, this does not work :-(. It is impossible to obtain the list of sorted columns at this moment.
>>
And the grid is still sorting clientside when I click on the headers. How do I turn this off? I only want to sort serverside.
<<
The grid cannot sort at the client side. When you click a column header, the ASPxGridView sends a callback to the server, sorts data in the server and then return the result back to the client. You may check it yourself - set a breakpoint in the Page_Load event and click a column header.
>>
Do you have any documentation and examples about server mode?..
<<
Please refer to the Server mode using LINQ? Let's wax rhapsodic. article and the screencast recorded by Mehul:
Screencast: Enable Server Mode using LINQ (ASPxGridView & XtraGrid)
Thanks,
Plato
Hi Plato,
It's okey that you not agree with me. :)
But this is why your gridview is more complicated to learn then others and why it's not possible (in an easy way) to apply sorting and paging to the grid server side. This should be 2 of the fundamental features of the grid!
All the features like grouping, filtering, summary and so on is great features BUT how often do you use them?! For me, I guess one of ten!
The rest, nine times, I just display rows from database as they are with just sorting and paging.
And now I have tried in different ways for about 2 weeks to sort and page the grid without success! It shouldn't be that hard. :(
So it's not working to get the sorted column in page_load! Is it a bug and will be fixed in next release?
Oh, the grid is not sorted client side. I didn't know it was a callback that made the sort.
Well, okey, the grid is sorted server side then! How do I turn that off?
Because the grid sorts when I click a header and I have not activated sorting in database yet with the test page.
So something is sorting the rows! :)
Have I understand this correct?
When using NHibernate it is not possible to sort and page the grid without using what you call "server mode"?
Regards
Mattias
Hi Matthias,
>>
So it's not working to get the sorted column in page_load! Is it a bug and will be fixed in next release?
<<
This is not a bug. The information about sorted columns is restored later.
>>
Well, okey, the grid is sorted server side then! How do I turn that off?
Because the grid sorts when I click a header and I have not activated sorting in database yet with the test page.
So something is sorting the rows! :)
<<
The ASPxGridView has a DataController, which sorts rows, groups rows, does all the required data manipulations. You can easily turn off sorting or even sending a callback to the server when the end-user presses a column header. Handle the client side ColumnSorting event and set the e.cancel parameter to true.
>>
Have I understand this correct?
When using NHibernate it is not possible to sort and page the grid without using what you call "server mode"?
<<
The ASPxGridView's DataController sorts data itself. It does not rely on the underlying DataSource at all. Sorting is done on the web server. So, in default mode, the ASPxGridView will properly sort, and data will be returned by your DataSource. The Paging will also work fine.
The server mode means that sorting, paging, filtering, … all ASPxGridView data related features are implemented on the DB server level. I did not answer to your first paragraph because I thought that this is an answer to both questions.
Thanks,
Plato
Okey, I give up! :(
I'll take your reply that it is not possible to use NHibernate with your grid and bind it code behind.
And I have done some reading about Linq To NHibernate and there is no final release yet and there will not be any in the near future.
So I can't use server mode!
I'm sorry to say this but then I must change to a gridview that has the feature to sort and page code behind, like Telrik or ComponentArt.
They both have sorting and paging events that I can use.
I hope you rethink this approach and build in these kind of features into the grid in the future!
Best Regards
Mattias
Hi Mattias,
We have discussed your question and decided to implement additional events. Please let us know which events you would like to see in the ASPxGridView.
Thanks,
Plato
Plato, that is so good news! :)
What I need is an event when I click on a header.
I was just evaluating and testing the Teleriks gridview and they have an event called SortCommand.
I'm needing just about the same as this:
protected void RadGrid1_SortCommand(object source, GridSortCommandEventArgs e)
{
if ("Name".Equals(e.CommandArgument))
{
e.Canceled = true;
GridSortExpression expression = new GridSortExpression();
expression.FieldName = "Name";
switch (e.OldSortOrder)
{
case GridSortOrder.None:
case GridSortOrder.Descending:
expression.SortOrder = GridSortOrder.Ascending;
e.Item.OwnerTableView.DataSource = GetData("Name", true, skip, take);
//Response.Write("asc");
break;
case GridSortOrder.Ascending:
expression.SortOrder = GridSortOrder.Descending;
e.Item.OwnerTableView.DataSource = GetData("Name", false, skip, take);
//Response.Write("desc");
break;
}
RadGrid1.CurrentPageIndex = 0;
e.Item.OwnerTableView.SortExpressions.AddSortExpression(expression);
e.Item.OwnerTableView.Rebind();
}
}
…
private IList<Swh.Wb8.Entities.Category> GetData(string sortColumn, bool sortOrder, int skip, int take)
{
IGenericDao<Swh.Wb8.Entities.Category> Dao = new GenericDao<Swh.Wb8.Entities.Category>();
IList<Swh.Wb8.Entities.Category> list = Dao.GetObjects(new Order(sortColumn, sortOrder), skip, take, out recordCount);
RadGrid1.VirtualItemCount = recordCount;
return list;
}
What happens is:
When I click a header I'll get the clicked column name and order(asc/desc) and sends the values to the database (GetData)
GetData returns the new rows and binds it to the grid.
Telerik also have the superb feature of what they call: VirtualItemCount.
As you see from my IList<T> from NHibernate I have an output parameter (recordcount) with the total rows in database.
I send in the recordcount into the grid so it can caluculate the paging mechanism. Fantastic! :)
If you can fix this you will be my hero! :)
Best Regards
Mattias
Hi Matthias,
I have registered the <Sclink id="S19661" /> suggestion on your behalf. You will be notified when its status is changed.
Thanks,
Plato