Link to home
Start Free TrialLog in
Avatar of cobolinx1
cobolinx1

asked on

Datagridview sorting by date

Currently I have a datagridview that I created the columns at run time and added data to it row by row. (No databinding) How do I make a column that has dates (01/01/2009) sortable by the date? It appears to interpret it as a string is there a way to say this is a date column treat it like a date not a string. I tried creating a cell template but it doesn't work. Do I have to make the data into YYYY-MM-DD format somehow when the user clicks the header and then switch it back?

Dim txtCelldate As DataGridViewCell = New DataGridViewTextBoxCell
        With txtCelldate
            'Put specifics about the cell here, such as backcolor, etc.
            .Style.Format = "DD/MM/YYYY"
        End With
Avatar of Meir Rivkin
Meir Rivkin
Flag of Israel image

u need to set the ValueType property of the column to DateTime, check this code snippet:
dataGridView1.ColumnCount = 3
dataGridView1.Columns(0).Name = "ID"
dataGridView1.Columns(0).ValueType = GetType(Integer)

dataGridView1.Columns(1).Name = "Name"
dataGridView1.Columns(1).ValueType = GetType(String)

dataGridView1.Columns(2).Name = "Date"
dataGridView1.Columns(2).ValueType = GetType(DateTime)

Open in new window

the 3rd column is type of DateTime and it expects DateTime objects...
The other alternative is to use something like a DataTable, and set it as the DataSource of the DataGridView.  But either way, the column that has the Date in it needs to be of a Date data type, like sedqwick explained.  

The benefit of using a DataTable is that it is very easy to work with, is sortable, and can be filtered very easy, which you won't be able to do just using the DataGridView.

Avatar of cobolinx1
cobolinx1

ASKER

I still treats the dates as strings when I sort them.
The problem with setting the datasource is that I have data that I need to convert before displaying it and there are some combobox fields that I have a datasource already associated with it so If the user clicks on the field there are values that may not be in the dataset that I would bind everything to.
from msdn:
The default sort mode of a DataGridViewTextBoxColumn is Automatic.
The default sort mode for other column types is NotSortable.

u can set SortMode property of the column to DataGridViewColumnSortMode.Automatic,
so if the ValueType is DateTime it will sort the column accordingly.
cobolinx,

Can you show me how you are populating the DataGridView?

I have it set to automatic.

  If dssubmissions.Tables(0).Rows.Count > 0 Then
            Dim i As Integer = 0
            While i < dssubmissions.Tables(0).Rows.Count
                dgvsubmissions.Rows.Add(Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
                dgvsubmissions.Rows(i).Cells("Sub ID").Value = dssubmissions.Tables(0).Rows(i).Item("Submission ID").ToString
                dgvsubmissions.Rows(i).Cells("PRO_ID").Value = dssubmissions.Tables(0).Rows(i).Item("PRO_ID").ToString
                dgvsubmissions.Rows(i).Cells("PrO_NAME").Value = dssubmissions.Tables(0).Rows(i).Item("PRONAME").ToString
             

                Try
                    dgvsubmissions.Rows(i).Cells("Type of Submission").Value = dssubmissions.Tables(0).Rows(i).Item("Type of Submission").ToString()

                Catch ex As Exception
                    Console.Write(ex.Message)
                End Try


                If dssubmissions.Tables(0).Rows(i).Item("Received Date").ToString().Trim <> "" Then
                    dgvsubmissions.Rows(i).Cells("Received Date").Value = CDate(dssubmissions.Tables(0).Rows(i).Item("Received Date")).ToShortDateString
                End If

                If dssubmissions.Tables(0).Rows(i).Item("Termination Date").ToString().Trim <> "" Then
                    dgvsubmissions.Rows(i).Cells("Termination Date").Value = CDate(dssubmissions.Tables(0).Rows(i).Item("Termination Date")).ToShortDateString
                End If

                dgvsubmissions.Rows(i).ReadOnly = True
                i +=  1
            End While
        End If
ASKER CERTIFIED SOLUTION
Avatar of Meir Rivkin
Meir Rivkin
Flag of Israel image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You can define a custom sort compare with the DataGridView.Sort method:

        dgvsubmissions.Sort(New DateTimeComparer())


Private Class DateTimeComparer
        Implements IComparer(Of DateTime)

        Public Function Compare(ByVal x As Date, ByVal y As Date) As Integer Implements System.Collections.Generic.IComparer(Of Date).Compare
            Return Date.Compare(x, y)
        End Function
    End Class

Open in new window

@TheLearnedOne

do i have 2 use custom sort comparer if the column type is datetime and sortmode is auto?
I get an unable to cast object of type datetimecompairer to type system.collections.icompairer
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That was a run-time error.

Here is a better example:


Private Class DescendingDateTimeComparer
        Implements IComparer

        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            Dim rowX As DataGridViewRow = CType(x, DataGridViewRow)
            Dim rowY As DataGridViewRow = CType(y, DataGridViewRow)
            Dim dateX As Date = rowX.Cells("DateColumn").Value
            Dim dateY As Date = rowY.Cells("DateColumn").Value
            Return Date.Compare(dateY, dateX)
        End Function
    End Class

Open in new window

You and sedgwik just made me realize something If I take the ToShortDateString off then it sorts fine.