注意:DataGridViewコントロールは、.NET Framework 2.0で新しく追加されました。
ここでは、通常では並び替えのできない列を基準とした並び替えや、通常の並び替えとは違った方法での並び替え、複数列を比較しての並び替えなどといったように、並び替え方をカスタマイズする方法を紹介します。
並べ替え方を指定する方法は、幾つかあります。DataGridViewで並び替えを行う方法としては、SortメソッドでIComparerを指定して呼び出す方法や、SortCompareイベントを処理する方法があります。また、DataGridViewのDataSourceプロパティにデータソースが設定されている場合は、DataView.Sortプロパティなどにより、データソースを並び替えます。これらについて、以下に一つずつ紹介します。
この方法は、DataGridViewのDataSourceプロパティが設定されておらず、VirtualModeプロパティがFalseの場合に使用できます。
DataGridView.Sortメソッドを使用して並び替え方を変更するには、IComparerを使用します。IComparerにより並び替えを行う方法は、「配列やコレクション内の要素を並び替える」で説明しています。よってここでは詳しくは説明せず、サンプルだけを示します。
以下に紹介する例では、はじめにインデックスが0番目の列を比較し、もしその列が同じならば次の列で比較を行うことにより、並び替えをしています。
まずは、次のようなIComparerインターフェイスを実装したクラスを作成します。
'IComparerインターフェイスを実装した、並び替える方法を定義したクラス Public Class CustomComparer Implements IComparer Private sOrder As Integer Private comparer As Comparer Public Sub New(ByVal order As SortOrder) Me.sOrder = IIf(order = SortOrder.Descending, -1, 1) Me.comparer = New Comparer( _ System.Globalization.CultureInfo.CurrentCulture) End Sub '並び替え方を定義する Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _ Implements System.Collections.IComparer.Compare Dim result As Integer = 0 Dim rowx As DataGridViewRow = CType(x, DataGridViewRow) Dim rowy As DataGridViewRow = CType(y, DataGridViewRow) 'はじめの列のセルの値を比較し、同じならば次の列を比較する For i As Integer = 0 To rowx.Cells.Count - 1 result = Me.comparer.Compare( _ rowx.Cells(i).Value, rowy.Cells(i).Value) If result <> 0 Then Exit For End If Next i '結果を返す Return result * Me.sOrder End Function End Class
//IComparerインターフェイスを実装した、並び替える方法を定義したクラス public class CustomComparer : IComparer { private int sortOrder; private Comparer comparer; public CustomComparer(SortOrder order) { this.sortOrder = (order == SortOrder.Descending ? -1 : 1); this.comparer = new Comparer( System.Globalization.CultureInfo.CurrentCulture); } //並び替え方を定義する public int Compare(object x, object y) { int result = 0; DataGridViewRow rowx = (DataGridViewRow)x; DataGridViewRow rowy = (DataGridViewRow)y; //はじめの列のセルの値を比較し、同じならば次の列を比較する for (int i = 0; i < rowx.Cells.Count; i++) { result = this.comparer.Compare( rowx.Cells[i].Value, rowy.Cells[i].Value); if (result != 0) break; } //結果を返す return result * this.sortOrder; } }
実際に並び替えを行うには、次のようなコードを書きます。ここでは、昇順で並び替えます。
'昇順で並び替えを行う DataGridView1.Sort(New CustomComparer(SortOrder.Ascending))
//昇順で並び替えを行う DataGridView1.Sort(new CustomComparer(SortOrder.Ascending));
この方法も、DataGridViewのDataSourceプロパティが設定されておらず、VirtualModeプロパティがFalseの場合に使用できます。
SortCompareイベントは、DataGridViewが並べ替えを行うために2つのセルの値を比較する時に発生します。このイベントは、DataGridViewColumn.SortModeプロパティがAutomaticの時にユーザーが列ヘッダーをクリックした時や、IComparerを使用せずにDataGridView.Sortメソッドを呼び出した場合にで並び替えを行った時に発生するため、これらにより並び替えが行われた時の並べ替え方を定義できます。
SortCompareイベントを使用する方法も、DataGridView.Sortメソッドを使用する方法を理解していれば、簡単です。SortCompareイベントハンドラで取得できるDataGridViewSortCompareEventArgsオブジェクトのCellValue1とCellValue2を比較し、CellValue1のほうが大きければ正の整数を、CellValue2のほうが大きければ負の整数を、両方同じならば0をSortResultプロパティに代入します。そして、HandledプロパティをTrueにします。
以下の例では、セルの値を文字列に変換した時の長さによって並び替えるようにしています。
'DataGridView1のSortCompareイベントハンドラ Private Sub DataGridView1_SortCompare(ByVal sender As Object, _ ByVal e As DataGridViewSortCompareEventArgs) _ Handles DataGridView1.SortCompare '指定されたセルの値を文字列として取得する Dim str1 As String If e.CellValue1 Is Nothing Then str1 = "" Else str1 = e.CellValue1.ToString End If Dim str2 As String If e.CellValue2 Is Nothing Then str2 = "" Else str2 = e.CellValue2.ToString End If '結果を代入 e.SortResult = str1.Length - str2.Length '処理したことを知らせる e.Handled = True End Sub
//DataGridView1のSortCompareイベントハンドラ private void DataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e) { //指定されたセルの値を文字列として取得する string str1 = (e.CellValue1 == null ? "" : e.CellValue1.ToString()); string str2 = (e.CellValue2 == null ? "" : e.CellValue2.ToString()); //結果を代入 e.SortResult = str1.Length - str2.Length; //処理したことを知らせる e.Handled = true; }
複数の列により並び替えを行う場合は、DataGridViewSortCompareEventArgsオブジェクトのRowIndex1とRowIndex2プロパティを使用します。この行インデックスからDataGridViewRowオブジェクトを取得して、比較を行います。
DataGridViewのDataSourceプロパティにデータソースが設定されている場合は、データソースを並び替えます。データソースの並び替えは、DataView.Sort プロパティやBindingSource.Sort プロパティなどで行うことができます。ここでは、DataView.Sortプロパティを使用する方法を紹介します。
例えばColumn1列を昇順で並び替えるなら、Sortプロパティを"Column1 ASC"とします。降順であれば、ASCの代わりにDESCとします。Column1とColumn2の2つの列で並び替えるなら、"Column1, Column2 ASC"(または"Column1 ASC, Column2 ASC")のようにします。
以下の例では、DataGridView1にDataTableがバインドされている時、Column1とColumn2列で昇順に並び替えています。並び替えグリフの表示も、2つの列で行っています。
'DataGridView1にバインドされているDataTableを取得 Dim dt As DataTable = CType(DataGridView1.DataSource, DataTable) 'DataViewを取得 Dim dv As DataView = dt.DefaultView 'Column1とColumn2で昇順に並び替える dv.Sort = "Column1, Column2 ASC" '2つの列のヘッダーに並び替えグリフを表示する DataGridView1.Columns("Column1").HeaderCell.SortGlyphDirection = _ SortOrder.Ascending DataGridView1.Columns("Column2").HeaderCell.SortGlyphDirection = _ SortOrder.Ascending
//DataGridView1にバインドされているDataTableを取得 DataTable dt = (DataTable)DataGridView1.DataSource; //DataViewを取得 DataView dv = dt.DefaultView; //Column1とColumn2で昇順に並び替える dv.Sort = "Column1, Column2 ASC"; //2つの列のヘッダーに並び替えグリフを表示する DataGridView1.Columns["Column1"].HeaderCell.SortGlyphDirection = SortOrder.Ascending; DataGridView1.Columns["Column2"].HeaderCell.SortGlyphDirection = SortOrder.Ascending;