Как мне реализовать автоматическую сортировку DataGridView? - PullRequest
13 голосов
/ 22 сентября 2010

Я программно добавляю столбцы в 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 ]

21 голосов
/ 18 ноября 2010

Мы используем BindingListView для привязки List s к DataGridViews, и это прекрасно работает для нас.

Вот очень простой пример создания представления списка объектов (в C #):

List<Customer> customers = GetCustomers();
BindingListView<Customer> view = new BindingListView<Customer>(customers);
dataGridView1.DataSource = view;

Проверьте https://stackoverflow.com/a/17952576/116891 для более подробной информации о сортировке DGV и привязке данных.

Если вы не хотите добавлять что-то более тяжелое, вы можете попробовать эту реализацию SortableBindingList ( с обновлениями ).

И то, и другое дает вам возможность сортировки прямо из коробки, а BindingListView даже быстрее, чем DataViews, согласно их тестам.

2 голосов
/ 11 апреля 2016

Лучшее решение, которое я нашел:

РЕДАКТИРОВАТЬ: С момента публикации я нашел эту реализацию 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.

1 голос
/ 18 ноября 2010

Я думаю, что нашел ответ. Мой источник данных реализует IList<T>. Видимо это нужно реализовать IBindingList<T>. К сожалению, я не могу это проверить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...