Как мне реализовать автоматическую сортировку DataGridView?
Я программно добавляю столбцы в 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;
3 ответа
Мы используем BindingListView для привязки List
Вот очень простой пример создания представления списка объектов (в C#):
List<Customer> customers = GetCustomers();
BindingListView<Customer> view = new BindingListView<Customer>(customers);
dataGridView1.DataSource = view;
Посетите /questions/4609694/kak-otsortirovat-winforms-datagridview-privyazannyij-k-ef-entitycollectiont/4609695#4609695 для получения более подробной информации о сортировке DGV и привязке данных.
Если вы не хотите добавлять что-то более тяжелое, вы можете попробовать эту реализацию SortableBindingList
Оба дают вам сортировку прямо из коробки, и 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
Затем реализуйте эти обработчики событий. Второй - убедиться, что сортировка по дате работает. Это нужно только в том случае, если в вашей сетке будет столбец сортируемых дат:
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>
, К сожалению, я не могу это проверить.