2009-05-15 58 views
3

WindowsフォームアプリケーションでDataGridViewコントロールを取得しました。文字列データを含む4つの列と、DateTimeデータを持つ3つの列があります。 Rows.Add()メソッドを使用してプログラムで行を追加しています。すべての列でSortModeがAutomaticに設定されています。列ヘッダーをクリックすると、並べ替えるだけで、いくつかのNULLを持つ1つのDateTime列を除いて動作します。ユーザーがその列のヘッダーをクリックすると、ArgumentExceptionがスローされます。オブジェクトはDateTime型でなければなりません。DataGridViewでDateTime列にnullをソートする

私はこれを回避する難しい方法を知っています:すべてのSortModesをNotSortableに設定し、ColumnHeaderMouseClickイベントを処理し、すべてを手動でソートします。私は簡単な方法を探しています。

私が設定できるプロパティや何か他の比較的簡単な方法で、この列がnullでソートできるようにしますか?

+0

DataGridViewがDataBoundの場合、ソートコンパイルは機能しません。これには他の選択肢がありますか? –

答えて

2

ここに私が思いついた解決策があります。 DataGridViewは、カスタムソートの入力に使用できるSortCompareイベントを発生させます。私はそのイベントを処理して、null値を非ヌル値よりも高く並べ替えることになります(ヌル以外の値よりも簡単にnullを作ることができます)。ここにVBコードがあります。 (それは通常のエラー処理ロジックによって処理されますされていない場合。)私はすべてのセルの値がIComparableをあると仮定してい

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 

誰もがこの上の任意の改善、それらを掲示すること自由に感じなさいを持っている場合。

+0

私の更新された答えを見てください。あなたが投稿したものがあなたの問題を解決したら、冷静にしてください。しかし、私の提案があなたにも役立つかどうかを知りたいと思っています。 –

+0

DataGridViewがDataBoundの場合、並べ替えが機能しません。これには他の選択肢がありますか? –

1

行を動的に追加する場合は、DataGridViewがDataboundではないと仮定する必要があります。 このケースでは、対応する行セルにデータを設定して何らかのダミーの日付をインスタンス化するときにnullをチェックしないでください(過去に面白い日付になっているので、nullだったことが明らかです - )それはソートになると、それは良いよ。

これはうまくいかない場合 - 継承を使用して組み込みのものと全く同じ独自のDataGridViewを作成するとどうなりますかBUTはnullを無視するソート方法を無効にしますか?

+0

あなたはそうです、それはDataBoundではありません。それは良い提案ですが、可能であればディスプレイにヌルを保持したいと考えています。私は計画Bとしてそれを保つだろう –

+0

ええと、大丈夫 - 新しい提案はどう?編集 – JohnIdol

+0

を参照してください。私はそのショットを与えるかもしれません。おそらくソートを手動で処理するよりも少ない作業ではありますが、少なくとももっと面白いでしょう。 –

1

更新回答: あなたの投稿の答えを見た後、私はあなたが細胞にDBNull.Valueのためにチェックしていることがわかります。これは、DBNull.ValueをDateTimeにキャストできないため、問題の原因となる可能性があります。プログラムで行を追加する場合は、DBNull.Valueをnull(Nothing)に置き換えてみてください。


オリジナル回答: 任意のデータがロードされ、好ましくは、前に、日付と時刻のデータを保持している列ごとにこれをやって試してみてください:フィルタ処理するとき

myDateTimeColumn.ValueType = GetType(DateTime) 

MSDNによると、ValueTypeプロパティ「を使用しますまたは列をセルの内容に関して並べ替えることができます。ですから、並べ替えを許可する列に対しては必ず設定してください。

このプロパティを設定すると、グリッドはNULLを持つ列でソートされ、挿入/更新されたセルを強制的にDateTimeに変換できます。

+0

ポストをありがとう。プログラムではなくデザイナーで列を定義していますが、複数の列があります。これらの2つの違いのいずれかが異なる結果を説明できるのだろうかと思います。 –

0

この質問にいくつかのコードを追加するだけです...私は、ヌルの存在下でのDateTime(および他の非文字列型)で正しく機能するために並べ替えを取得するには、以下のなかった:

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); 
} 
4

簡単な解決策は、「tonull」機能を追加することで、あなたは電子を実行します.cellvalue1と2を比較するたびに。値が ""の場合、セルの値は01/01/1001に変更され、null値がソートまたは01/01/3001に最初に表示されるようにするか、最後に表示したい場合は非常に高い値にしますソート。

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 
関連する問題