79

I need to resort, in memory, a DataTable based on a column and direction that are coming from a GridView. The function needs to look like this:

public static DataTable resort(DataTable dt, string colName, string direction)
{
    DataTable dtOut = null;

    ....
}

I need help filling in this function. I think I can use a Select statement but I am not sure how. I can't click on Comments because of this browser but you can show me an in-place or new DataTable solution, either one. For the people showing me pointers, please, I need a coded function similar to the one prototyped.

How about:

// ds.Tables[0].DefaultView.Sort="au_fname DESC";
   public static void Resort(ref DataTable dt, string colName, string direction)
   {
        string sortExpression = string.Format("{0} {1}", colName, direction);
        dt.DefaultView.Sort = sortExpression;
   }
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Sam Gentile
  • 1,259
  • 7
  • 22
  • 28

6 Answers6

117

I assume "direction" is "ASC" or "DESC" and dt contains a column named "colName"

public static DataTable resort(DataTable dt, string colName, string direction)
{
    DataTable dtOut = null;
    dt.DefaultView.Sort = colName + " " + direction;
    dtOut = dt.DefaultView.ToTable();
    return dtOut;
}

OR without creating dtOut

public static DataTable resort(DataTable dt, string colName, string direction)
{
    dt.DefaultView.Sort = colName + " " + direction;
    dt = dt.DefaultView.ToTable();
    return dt;
}
Berkay Turancı
  • 3,373
  • 4
  • 32
  • 45
  • This seems to work the first time but not subsequent times. When I set my defaultView.Sort a second time to a different column direction, the table in the gridView diappears.... – N romaai Aug 30 '13 at 20:09
  • Hmm, looks like it's overwriting the tableStyles.GridCOlumnStyles – N romaai Aug 30 '13 at 20:22
  • 3
    You can also simplify the second code block to simply return `dt.DefaultView.ToTable();`. – MattD Oct 07 '15 at 19:59
70

If you've only got one DataView, you can sort using that instead:

table.DefaultView.Sort = "columnName asc";

Haven't tried it, but I guess you can do this with any number of DataViews, as long as you reference the right one.

Benny Skogberg
  • 10,431
  • 11
  • 53
  • 83
Alex
  • 2,681
  • 3
  • 28
  • 43
  • great! this solution works and is 10x easier than all of these custom sort methods – user1985189 Mar 05 '13 at 19:09
  • Not sure why the other solution has more upvotes but this is the one you are after if you came to this thread. Thanks Alex. It works. – kuklei Mar 02 '16 at 22:03
20

Actually got the same problem. For me worked this easy way:

Adding the data to a Datatable and sort it:

dt.DefaultView.Sort = "columnname";
dt = dt.DefaultView.ToTable();
Kᴀτᴢ
  • 2,146
  • 6
  • 29
  • 57
7

DataTables have an overloaded Select method that you can you to do this. See here: http://msdn.microsoft.com/en-us/library/way3dy9w.aspx

But the return val of the Select call is not a DataTable but an array of RowData objects. If you want to return a DataTable from your function you will have to build it from scratch based on that data array. Here is a post that addresses and provides a sample for both issues: http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/157a4a0f-1324-4301-9725-3def95de2bf2/

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
5

In case you want to sort in more than one direction

  public static void sortOutputTable(ref DataTable output)
        {
            DataView dv = output.DefaultView;
            dv.Sort = "specialCode ASC, otherCode DESC";
            DataTable sortedDT = dv.ToTable();
            output = sortedDT;
        }
Evan Parsons
  • 1,139
  • 20
  • 31
4

Create a DataView. You cannot sort a DataTable directly, but you can create a DataView from the DataTable and sort that.

Creating: http://msdn.microsoft.com/en-us/library/hy5b8exc.aspx

Sorting: http://msdn.microsoft.com/en-us/library/13wb36xf.aspx

The following code example creates a view that shows all the products where the number of units in stock is less than or equal to the reorder level, sorted first by supplier ID and then by product name.

DataView prodView = new DataView(prodDS.Tables["Products"], "UnitsInStock <= ReorderLevel", "SupplierID, ProductName", DataViewRowState.CurrentRows);

Jakub Konecki
  • 45,581
  • 7
  • 87
  • 126