none
DataGridView - Sorting DateTime columns

    Question

  • I'm using datagridview controls but cannot figure out how to get it to sort datetime fields.  Basically, I've got datetime fields bound to textcolumns, and of course, it sorts them like strings not dates.  Any ideas here?  I'm binding to collections not datasets.  Any ideas would be appreciated.  I've tried using the SortCompare Event, but it never fires.
    Friday, January 20, 2006 3:37 AM

All replies

  • When you bind DateTime values to DataGridViewColumn, it sorts fine, how do you bind excactly?

     

    anyway, I'm here is a code I've posted to how to sort multi columns on a datagridview, check it out, this is the correct way to implement custom sorting on the grid :

     

    To allow multi sort on a DataGridView call this method (this is a DataGridView extended object) :



    /// <summary>
    /// Multi sort the grid.
    /// The sort order will be from 0 item on the columnNamesToSort array until 
    /// the N-1 item. Sort order is used to determine ascending/descending or none
    /// options. if no sort order items are set, default is acsending.
    /// </summary>
    /// <param name="columnNamesToSort">column names to sort, starting from item 0</param>
    /// <param name="sortOrder">sorting order array matching the columns name array</param>
    /// <returns></returns>
    public bool MultiSort(string[] columnNamesToSort, SortOrder[] sortOrder)
    {
    if (columnNamesToSort != null && columnNamesToSort.Length > 0)
    {
    this.Sort(new MultiSortComparer(
    columnNamesToSort, sortOrder
    ));
    return true;
    }
    return false;
    }




    This is the multiSort class that I use to allow the multi sort:


    public class MultiSortComparer : System.Collections.IComparer
    {
    private string[] columnNames;
    private SortOrder[] columnOrder;

    public MultiSortComparer(string[] columnNames, SortOrder[] columnOrder)
    {
    this.columnNames = columnNames;
    this.columnOrder = columnOrder;
    }

    public int Compare(object x, object y)
    {
    DataGridViewRow row1 = (DataGridViewRow)x;
    DataGridViewRow row2 = (DataGridViewRow)y;

    // the comapre result to send in the end of the method
    int compareResult = 0;
    string compareColumn = "";
    // the column index to compare by at wach iteration
    int columnIndex = 0;
    // sort will continue until compare_result != 0
    bool isSortNedded = true;
    while (isSortNedded)
    {
    compareColumn = columnNames[columnIndex];
    compareResult =
    Compare_Object(row1.Cells[compareColumn].Value,
       row2.Cells[compareColumn].Value);



    // continue to next cell index
    ++columnIndex;
    // if cells are equal --> continue comapre at next cell                 
    // also, end of loop when there are no more column to check
    isSortNedded = (compareResult == 0) &&
    (columnIndex < columnNames.Length);
    }
    // the result is multiply by up and down settings
    // dec index by one because its added before for next iteration
    int sortOrderValue = 0;
    if (columnOrder == null || 
    columnOrder.Length <= columnIndex - 1 ||
    columnOrder[columnIndex - 1] == SortOrder.None)
    {
    sortOrderValue = 0;
    }
    else
    {
    sortOrderValue = (columnOrder[columnIndex - 1] == SortOrder.Ascending ? 1 : -1);
    }
    return compareResult * sortOrderValue;
    }

    private int Compare_Object(object o1, object o2)
    {
    // object are null - equal
    if (o1 == null && o2 == null) return 0;
    // o1 is null o2 is not - o2 is bigger
    if (o1 == null && o2 != null) return -1;
    // o2 is null o1 is not - o1 is bigger
    if (o1 != null && o2 == null) return 1;
    // o1 and o2 is not the same type - equal
    if (o1.GetType() != o2.GetType()) return 0;
    // int or double or float or long
    if (o1 is string)
    {
    string s1 = o1.ToString();
    string s2 = o2.ToString();
    return s1.CompareTo(s2);
    }
    if (o1 is DateTime)
    {
    DateTime d1 = (DateTime)o1;
    DateTime d2 = (DateTime)o2;
    return d1.CompareTo(d2);
    }

    if (o1 is int)
    {
    int n1 = (int)o1;
    int n2 = (int)o2;
    return (n1 > n2 ? 1 :
    n1 < n2 ? -1 : 0);
    }
    if (o1 is bool)
    {
    bool b1 = (bool)o1;
    bool b2 = (bool)o2;
    return (b1 == b2 ? 0: b1==true ? 1 : -1);


    if (o1 is float)
    {
    float n1 = (float)o1;
    float n2 = (float)o2;
    return (n1 > n2 ? 1 :
    n1 < n2 ? -1 : 0);

    if (o1 is double)
    {
    double n1 = (double)o1;
    double n2 = (double)o2;
    return (n1 > n2 ? 1 :
    n1 < n2 ? -1 : 0);
    }
    if (o1 is long)
    {
    long n1 = (long)o1;
    long n2 = (long)o2;
    return (n1 > n2 ? 1 :
    n1 < n2 ? -1 : 0);
    }

    return 0;



    }
    }



    Hope it helps.

    Eli

    Friday, January 20, 2006 8:44 AM
  • I don't really need the multisort ability (I think).  I'm using VB.net and I'm binding to a bussiness collection.  I made a custom version of the DataGridView because it was such a pain to add columns.  Here is the code I use to a textcolumn.

    Public Sub AddGridColumn(ByVal DataField As String, ByVal HeaderText As String, Optional ByVal width As Integer = Nothing, Optional ByVal isVisible As Boolean = True)

    Me.Columns.Add(DataField, HeaderText)

    With Me.Columns(DataField)

    .DataPropertyName = DataField

    If (width <> Nothing) Then .Width = width

    .Visible = isVisible

    End With

    End Sub

    This is the actual code in my form that binds to this custom grid:

    With dvWO

    .AutoGenerateColumns = False

    .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None

    .SuspendLayout()

    .AddGridColumn("woID", "woID", 100, False)

    .AddGridColumn("WorkOrderNumberString", "Work Order#", 100)

    .AddGridColumn("Status", "Status", 100)

    .AddGridColumn("DateReported", "DateReported", 100)

    .AddGridColumn("CustomerName", "Customer", 100)

    .AddGridColumn("EmployeeName", "Technician", 100)

    .AddGridColumn("ServiceType", "ServiceType", 100)

    .AddGridColumn("DateScheduled", "DateScheduled", 100)

    .DataSource = WOlist

    End With

    Friday, January 20, 2006 4:15 PM
  • Check this link:

    http://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_fxmclictl/html/e79a9d4e-64ec-41f5-93ec-f5492633cbb2.asp

    or maybe bind the data to DataTable, this way you can specified the object type of each column.

     

    Friday, January 20, 2006 11:44 PM