Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a GridView bound to a list of custom generic Objects

I'm trying to figure out how to sort a GridView with multiple columns (String, DateTime, Decimal, etc. data-types) which is bound to a generic list of custom objects.

MyObject.vb:

Public Property Id
Public Property Name
Public Property Date
Public Property Amount

MyObjects.aspx.vb:

gridView.DataSource = GetMyObjects()
gridView.DataBind()

Note: GetMyObjects() returns a List of MyObject

Basically, I need to be able to click on the column headers of the grid to sort and reverse sort, and also be able to store the sort direction in ViewState so the direction persists each time I click on a column header.

It seems like I probably need MyObject to implement IComparable, but I'm not sure quite how to put it all together.

Can anyone suggest a good tutorial for this, or point me in the right direction?

like image 447
Prabhu Avatar asked Sep 28 '12 17:09

Prabhu


1 Answers

You need to enable sorting (AllowSorting) and handle the event OnSorting.

Note: The sample code uses C#, but the VB version should be similar.

Create your GridView:

<asp:GridView ID="GridView1" runat="server" AllowSorting="True" OnSorting="GridView1_Sorting">
</asp:GridView>

Handle OnSorting:

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    GridView1.DataSource = GetObjects(e.SortDirection, e.SortExpression);
    GridView1.DataBind();
}

GetObjects returns a sorted List<MyObject>. You have to create your own sorting logic here, one alternative could be using Dynamic Linq. If you choose that route, GetObjects could be defined like this: (there are better ways, but this is enough to show the theory)

private List<MyObject> GetObjects(SortDirection sd, string se)
{
    // Have we generated data before?
    if (SimulatedDB == null)
    {
        // Create a sample DB
        SimulatedDB = new List<MyObject>();
        var rnd = new Random();

        for (int i = 0; i < 20; i++)
        {
            var node = new MyObject();
            node.Id = i;
            node.Name = String.Format("Name {0}", i);
            node.CreationDate = DateTime.Now.AddDays(rnd.Next(100));
            node.Amount = (rnd.Next(1000) * rnd.NextDouble());

            SimulatedDB.Add(node);
        }
    }

    // Return sorted list
    if (sd == SortDirection.Ascending)
        return SimulatedDB.AsQueryable<MyObject>().OrderBy<MyObject>(se).ToList();
    else
        return SimulatedDB.AsQueryable<MyObject>().OrderByDescending<MyObject>(se).ToList();
}

Hope it helps.

like image 84
Daniel Avatar answered Sep 23 '22 06:09

Daniel