注意:DataGridViewコントロールは、.NET Framework 2.0で新しく追加されました。
DataGridViewColumn.SortModeプロパティがDataGridViewColumnSortMode.Automaticの時(DataGridViewTextBoxColumnではデフォルト)は、ユーザーが列をクリックすると、その列の内容でデータが並び替えられます。DataGridViewのDataSourceプロパティに並び替えが可能なデータソースが設定されており、仮想モードでない場合は、ユーザーが並び替えを行った後に新しい行を追加したり、セルの値を変更しても、その都度自動的に並び替えられます(詳細は、下記補足)。
プログラムで並び替えを行うには、DataGridView.Sortメソッドを使用します。Sortメソッドで並び替えられた後も、SortModeプロパティがAutomaticやProgrammaticであれば、ユーザーが列をクリックして並び替えたのと同じように、自動的に並び替えられます(詳細は、下記補足)。
補足:MSDN「DataGridViewRowCollection.Add メソッド」には、
「新しい行の追加時にコントロール内の行が自動的に並べ替えられることはありません。...また、CellValueChanged イベント ハンドラで System.Windows.Forms.DataGridView.Sort メソッドを呼び出すことにより、セルがユーザーによって変更されたときに行を並べ替えることもできます。」
とあり、DataGridViewに新しい行が追加されたり、セルの値が変更されたとしても、自動的に並び替えられることはないということになっています。しかし、DataGridViewのDataSourceプロパティが設定されており、仮想モードでない場合は、自動的に並び替えられるようです。これは、DataGridViewに自動的に並び替える機能はないが、データソースが自動的に並び替えられたということだと思われます。
プログラムで並び替えを行う例を紹介します。以下に示す例では、Button1をクリックすることにより、現在のセルの列で並び替えを行います。現在並び替えが行われている列とこれから並び替えを行う列が同じ場合は、昇順と降順をトグルで入れ替えて、それ以外では昇順で並び替えを行います。
'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '自動的に並び替えられるようにする Dim c As DataGridViewColumn For Each c In DataGridView1.Columns c.SortMode = DataGridViewColumnSortMode.Automatic Next c End Sub 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click If DataGridView1.CurrentCell Is Nothing Then Return End If '並び替える列を決める Dim sortColumn As DataGridViewColumn = _ DataGridView1.CurrentCell.OwningColumn '並び替えの方向(昇順か降順か)を決める Dim sortDirection As System.ComponentModel.ListSortDirection = _ System.ComponentModel.ListSortDirection.Ascending If Not (DataGridView1.SortedColumn Is Nothing) AndAlso _ DataGridView1.SortedColumn.Equals(sortColumn) Then sortDirection = IIf(DataGridView1.SortOrder = SortOrder.Ascending, _ System.ComponentModel.ListSortDirection.Descending, _ System.ComponentModel.ListSortDirection.Ascending) End If '並び替えを行う DataGridView1.Sort(sortColumn, sortDirection) End Sub
//フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //自動的に並び替えられるようにする foreach (DataGridViewColumn c in DataGridView1.Columns) c.SortMode = DataGridViewColumnSortMode.Automatic; } //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { if (DataGridView1.CurrentCell == null) return; //並び替える列を決める DataGridViewColumn sortColumn = DataGridView1.CurrentCell.OwningColumn; //並び替えの方向(昇順か降順か)を決める ListSortDirection sortDirection = ListSortDirection.Ascending; if (DataGridView1.SortedColumn != null && DataGridView1.SortedColumn.Equals(sortColumn)) { sortDirection = DataGridView1.SortOrder == SortOrder.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending; } //並び替えを行う DataGridView1.Sort(sortColumn, sortDirection); }
自動的に並び替えが行われない場合は、自分で並び替えを行います。さらに、SortModeプロパティがProgrammaticの場合は、並び替えグリフ(列ヘッダーの右側に表示される、昇順、降順のどちらで並び替えが行われているかを示す矢印)の表示も自分で行います。
列ヘッダーをクリックした時に並び替えを行うには、DataGridView.ColumnHeaderMouseClickイベントハンドラでSortメソッドを呼び出します。新しい行の追加後や、セルの編集後に並び替えが行われるようにするには、RowsAddedやCellValueChangedイベントハンドラでもSortメソッドを呼び出します。
また、並び替えグリフを表示するには、DataGridViewColumnHeaderCell.SortGlyphDirectionプロパティを設定します。
自動的に並び替えられないときでも、自動的に並び替えが行われるようにする例を以下に示します。列ヘッダーをクリックすると、その列を基準に、昇順、降順をトグルで変えて、並び替えが行われます。
'ColumnHeaderMouseClickイベントハンドラ Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, _ ByVal e As DataGridViewCellMouseEventArgs) _ Handles DataGridView1.ColumnHeaderMouseClick Dim clickedColumn As DataGridViewColumn = _ DataGridView1.Columns(e.ColumnIndex) If clickedColumn.SortMode <> DataGridViewColumnSortMode.Automatic Then Me.SortRows(clickedColumn, True) End If End Sub 'RowsAddedイベントハンドラ Private Sub DataGridView1_RowsAdded(ByVal sender As Object, _ ByVal e As DataGridViewRowsAddedEventArgs) _ Handles DataGridView1.RowsAdded Me.SortRows(DataGridView1.SortedColumn, False) End Sub 'CellValueChangedイベントハンドラ Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, _ ByVal e As DataGridViewCellEventArgs) _ Handles DataGridView1.CellValueChanged If Not (DataGridView1.SortedColumn Is Nothing) AndAlso _ e.ColumnIndex = DataGridView1.SortedColumn.Index Then Me.SortRows(DataGridView1.SortedColumn, False) End If End Sub ''' <summary> ''' 指定された列を基準にして並び替えを行う ''' </summary> ''' <param name="sortColumn">基準にする列</param> ''' <param name="orderToggle">並び替えの方向をトグルで変更する</param> Private Sub SortRows(ByVal sortColumn As DataGridViewColumn, _ ByVal orderToggle As Boolean) If sortColumn Is Nothing Then Return End If '今までの並び替えグリフを消す If sortColumn.SortMode = DataGridViewColumnSortMode.Programmatic AndAlso _ Not (DataGridView1.SortedColumn Is Nothing) AndAlso _ Not DataGridView1.SortedColumn.Equals(sortColumn) Then DataGridView1.SortedColumn.HeaderCell.SortGlyphDirection = _ SortOrder.None End If '並び替えの方向(昇順か降順か)を決める Dim sortDirection As System.ComponentModel.ListSortDirection If orderToggle Then sortDirection = IIf(DataGridView1.SortOrder = SortOrder.Descending, _ System.ComponentModel.ListSortDirection.Ascending, _ System.ComponentModel.ListSortDirection.Descending) Else sortDirection = IIf(DataGridView1.SortOrder = SortOrder.Descending, _ System.ComponentModel.ListSortDirection.Descending, _ System.ComponentModel.ListSortDirection.Ascending) End If Dim sOrder As SortOrder = _ IIf(sortDirection = System.ComponentModel.ListSortDirection.Ascending, _ SortOrder.Ascending, SortOrder.Descending) '並び替えを行う DataGridView1.Sort(sortColumn, sortDirection) If sortColumn.SortMode = DataGridViewColumnSortMode.Programmatic Then '並び替えグリフを変更 sortColumn.HeaderCell.SortGlyphDirection = sOrder End If End Sub
//フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //イベントハンドラの追加 DataGridView1.RowsAdded += new DataGridViewRowsAddedEventHandler( DataGridView1_RowsAdded); DataGridView1.CellValueChanged += new DataGridViewCellEventHandler( DataGridView1_CellValueChanged); DataGridView1.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler( DataGridView1_ColumnHeaderMouseClick); } //ColumnHeaderMouseClickイベントハンドラ private void DataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { DataGridViewColumn clickedColumn = DataGridView1.Columns[e.ColumnIndex]; if (clickedColumn.SortMode != DataGridViewColumnSortMode.Automatic) this.SortRows(clickedColumn, true); } //RowsAddedイベントハンドラ private void DataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { this.SortRows(DataGridView1.SortedColumn, false); } //CellValueChangedイベントハンドラ private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (DataGridView1.SortedColumn != null && e.ColumnIndex == DataGridView1.SortedColumn.Index) this.SortRows(DataGridView1.SortedColumn, false); } /// <summary> /// 指定された列を基準にして並び替えを行う /// </summary> /// <param name="sortColumn">基準にする列</param> /// <param name="orderToggle">並び替えの方向をトグルで変更する</param> private void SortRows(DataGridViewColumn sortColumn, bool orderToggle) { if (sortColumn == null) return; //今までの並び替えグリフを消す if (sortColumn.SortMode == DataGridViewColumnSortMode.Programmatic && DataGridView1.SortedColumn != null && !DataGridView1.SortedColumn.Equals(sortColumn)) { DataGridView1.SortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None; } //並び替えの方向(昇順か降順か)を決める ListSortDirection sortDirection; if (orderToggle) { sortDirection = DataGridView1.SortOrder == SortOrder.Descending ? ListSortDirection.Ascending : ListSortDirection.Descending; } else { sortDirection = DataGridView1.SortOrder == SortOrder.Descending ? ListSortDirection.Descending : ListSortDirection.Ascending; } SortOrder sortOrder = sortDirection == ListSortDirection.Ascending ? SortOrder.Ascending : SortOrder.Descending; //並び替えを行う DataGridView1.Sort(sortColumn, sortDirection); if (sortColumn.SortMode == DataGridViewColumnSortMode.Programmatic) { //並び替えグリフを変更 sortColumn.HeaderCell.SortGlyphDirection = sortOrder; } }