プログラムでDataGridViewに列を追加してから、リストにバインドしています。デフォルトでは、列のSortModeは自動です。しかし、アプリを実行するとき、ヘッダーをクリックしても何も起こりません。上/下矢印が表示されていません。 MSDNを読んでから、自動ソートについてはあまり語られていません。プログラムによる並べ替えについて詳しく説明します。だから、自動の方法は簡単なはずだと思います。 MSDNはさらに、「列ヘッダーが選択に使用されていない限り、列ヘッダーをクリックすると、DataGridViewがこの列で自動的に並べ替えられ、並べ替え順序を示すグリフが表示されます」と続けています。それは正確にはどういう意味ですか?並べ替えと競合するグリッドプロパティを設定できますか?何が足りないのですか?
AutoGenerateColumns = false;
AllowUserToAddRows = false;
AllowUserToDeleteRows = false;
AllowUserToResizeRows = false;
AllowUserToResizeColumns = false;
ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
ReadOnly = true;
MultiSelect = false;
RowHeadersVisible = false;
SelectionMode = DataGridViewSelectionMode.FullRowSelect;
CellBorderStyle = DataGridViewCellBorderStyle.None;
DataGridViewTextBoxColumn idColumn = new DataGridViewTextBoxColumn();
idColumn.HeaderText = "ID";
idColumn.DataPropertyName = "IDNumber";
DataGridViewTextBoxColumn nameColumn = new DataGridViewTextBoxColumn();
nameColumn.HeaderText = "Name";
nameColumn.DataPropertyName = "Description";
DataGridViewTextBoxColumn lastModifiedColumn = new DataGridViewTextBoxColumn();
lastModifiedColumn.HeaderText = "Last Modified";
lastModifiedColumn.DataPropertyName = "Date";
Columns.Add(idColumn);
Columns.Add(nameColumn);
Columns.Add(lastModifiedColumn);
List<IMyObject> bindingList = GetMyList();
DataSource = bindingList;
BindingListView を使用してList <T>をDataGridViewsにバインドしますが、これはうまく機能しています。
オブジェクトのリストのビューを作成する非常に簡単な例を次に示します(C#で)。
List<Customer> customers = GetCustomers();
BindingListView<Customer> view = new BindingListView<Customer>(customers);
dataGridView1.DataSource = view;
DGVの並べ替えとデータバインディングの詳細については、 https://stackoverflow.com/a/17952576/116891 をご覧ください。
それほど重いものを追加したくない場合は、この実装を試すことができます SortableBindingList <T> ( 更新あり )。
ベンチマークによると、どちらも箱から出してすぐに並べ替えることができ、BindingListViewはDataViewsよりもさらに高速です。
編集:投稿してから、この SortableBindingList(Of T)
の実装が最良の解決策であることがわかりました。コンストラクターがとにかくキャストしていて機能するので、52行目をIEnumerable
ではなくICollection
に変更しました。
DataGridView
は、カスタムクラスを実装せずに並べ替えることができます。私のコードはVB.NETにありますが、変換する必要があることに注意してください。データは最初にgrid.Rows
に追加する必要があります。
For Each item In dataList
grid.Rows.Add(item.Id, item.Name, item.DateProperty)
Next
次に、これらのイベントハンドラーを実装します。 2つ目は、日付の並べ替えが機能することを確認することです。グリッドに並べ替え可能な日付列がある場合にのみ必要です。
Private Sub grid_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles grid.ColumnHeaderMouseClick
Dim col = grid.Columns(e.ColumnIndex)
Dim dir As System.ComponentModel.ListSortDirection
Select Case col.HeaderCell.SortGlyphDirection
Case SortOrder.None, SortOrder.Ascending
dir = System.ComponentModel.ListSortDirection.Ascending
Case Else
dir = System.ComponentModel.ListSortDirection.Descending
End Select
grid.Sort(col, dir)
End Sub
Private Sub grid_SortCompare(ByVal sender As Object, ByVal e As DataGridViewSortCompareEventArgs) Handles grid.SortCompare
'This event occurs only when the DataSource property is not set and the VirtualMode property value is false.
If e.Column.Name = "DateProperty" Then
e.SortResult = Date.Compare(CType(e.CellValue1, Date), CType(e.CellValue2, Date))
e.Handled = True
End If
End Sub
注意すべき重要な点は、バインディングがないため、行に追加したプロパティのみが結果のオブジェクトの一部であるということです。オブジェクト全体を維持するには、すべてのプロパティに列を追加し、表示されるべきでない列にVisible = False
列を設定する必要があります。
私は答えを見つけたと思います。私のデータソースはIList<T>
を実装しています。どうやらそれはIBindingList<T>
を実装する必要があります。残念ながら、これをテストすることはできません。