DataGridView sorting with nulls in DateTime column

前端 未结 5 1175
猫巷女王i
猫巷女王i 2021-01-14 04:30

I\'ve got a DataGridView control in a Windows forms application. There are four columns with string data and three with DateTime data. I\'m adding the rows programmatically

相关标签:
5条回答
  • 2021-01-14 04:45

    If you're adding rows dynamically I must assume the DataGridView is not Databound. In this case why don't you check for nulls when populating the correspondent row cells and instantiate some kind of dummy date (some funny date in the past so that it's clear that it was a null - maybe also specify that it's a default value) so that when it comes to sorting it's ll good.

    If this ain't good - what about creating your own DataGridView exactly the same as the built-in one (using inheritance) BUT overriding the sorting method to ignore nulls?

    0 讨论(0)
  • 2021-01-14 04:45

    Updated Answer: After looking at your posted answer, I see that you're checking for DBNull.Value in the cells. That may be the source of your problem since DBNull.Value can't be cast to a DateTime. If you're programmatically adding the rows, try replacing DBNull.Value with null (Nothing).


    Original Answer: Try doing this for each column that holds DateTime data, preferably before any data is loaded:

    myDateTimeColumn.ValueType = GetType(DateTime)
    

    According to MSDN, the ValueType property is "used when filtering or sorting the columns with respect to the contents of their cells." So I would be sure to set it for any column that allows sorting.

    With this property set, the grid can be sorted on a column that has nulls and will force inserted/updated cells to be converted to DateTime.

    0 讨论(0)
  • 2021-01-14 04:54

    An easy solution is to add a "tonull" function, which you run the e.cellvalue1 and 2 through each time a comparison is made. If the value is "" then the value of the cell will be changed to 01/01/1001 if you want null values to appear first on the sort or 01/01/3001 or something ridiculously high if you want them to appear last on the sort.

    Private Sub dgvTable_SortCompare(ByVal sender As Object, ByVal e As DataGridViewSortCompareEventArgs) Handles dgvTable.SortCompare
    
        If e.Column.Index = 4 Then
    
            e.SortResult = System.DateTime.Compare(todatenull(e.CellValue1), todatenull(e.CellValue2))
    
        End If
    
        e.Handled = True
    End Sub
    
    
    Function todatenull(ByVal cellvalue)
        If cellvalue = "" Then
            Return "01/01/1001"
        Else
            Return cellvalue
        End If
    End Function
    
    0 讨论(0)
  • 2021-01-14 04:58

    Here's the solution I came up with. The DataGridView raises a SortCompare event that you can use to input custom sorting. I'm handling that event and making null values sort out higher than non-null values (you could just as easily make nulls lower than non-nulls). Here's the VB code. I'm assuming every cell value is IComparable (if not it will be handled by the normal error handling logic.)

    Try
        If e.CellValue1 Is Nothing OrElse e.CellValue1.Equals(DBNull.Value) Then
            If e.CellValue2 Is Nothing OrElse e.CellValue2.Equals(DBNull.Value) Then
                e.SortResult = 0
            Else
                e.SortResult = 1
            End If
        Else
            If e.CellValue2 Is Nothing OrElse e.CellValue2.Equals(DBNull.Value) Then
                e.SortResult = -1
            Else
                e.SortResult = DirectCast(e.CellValue1, IComparable).CompareTo(DirectCast(e.CellValue2, IComparable))
            End If
        End If
        e.Handled = True
    Catch ex As Exception
        HandleError("Error sorting result grid values", ex)
        Close()
    End Try
    

    If anybody has any improvements on this please feel free to post them.

    0 讨论(0)
  • 2021-01-14 05:10

    Just to add some code to this question... I did the following to get sorting to work correctly for DateTime (and other non-string types) in the presence of nulls:

    public MyFormCTor() {
        ...
        m_dataGridView.SortCompare += MySortCompare;
        ...
    }
    
    ...
    
    static void MySortCompare(object sender, DataGridViewSortCompareEventArgs e)
    {
        if (e.CellValue1 == e.CellValue2)
        {
            e.SortResult = 0;
            return;
        }
    
        if (e.CellValue1 == null)
        {
            e.SortResult = -1;
            return;
        }
    
        if (e.CellValue2 == null)
        {
            e.SortResult = 1;
            return;
        }
    
        e.SortResult = ((IComparable)e.CellValue1).CompareTo(e.CellValue2);
    }
    
    0 讨论(0)
提交回复
热议问题