Как включить сортировку DataGridView, когда пользователь нажимает на заголовок столбца? - PullRequest
66 голосов
/ 05 апреля 2011

В моей форме есть сетевое представление, и я заполняю его:

dataGridView1.DataSource = students.Select(s => new { ID = s.StudentId, RUDE = s.RUDE, Nombre = s.Name, Apellidos = s.LastNameFather + " " + s.LastNameMother, Nacido = s.DateOfBirth })
                                   .OrderBy(s => s.Apellidos)
                                   .ToList();

Теперь я использую s.Apellidos в качестве сортировки по умолчанию, но я также хотел бы разрешить пользователям сортировать при нажатии на заголовок столбца.

Этот тип не изменяет данные каким-либо образом, это всего лишь бонус со стороны клиента, чтобы упростить поиск информации при сканировании экрана их глазами.

Спасибо за предложения.

Ответы [ 15 ]

0 голосов
/ 18 августа 2018

В моем случае проблема заключалась в том, что я установил DataSource как object, поэтому он не был отсортирован. После изменения с object на DataTable все заработало без дополнения кода.

0 голосов
/ 16 февраля 2018

поместите эту строку в форму Windows (при загрузке или лучше в публичном методе, таком как "binddata"):

//
// bind the data and make the grid sortable 
//
this.datagridview1.MakeSortable( myenumerablecollection ); 

Поместите этот код в файл с именем DataGridViewExtensions.cs (или аналогичный)

// MakeSortable extension. 
// this will make any enumerable collection sortable on a datagrid view.  

//
// BEGIN MAKESORTABLE - Mark A. Lloyd
//
// Enables sort on all cols of a DatagridView 

//



    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    public static class DataGridViewExtensions
    {
    public static void MakeSortable<T>(
        this DataGridView dataGridView, 
        IEnumerable<T> dataSource,
        SortOrder defaultSort = SortOrder.Ascending, 
        SortOrder initialSort = SortOrder.None)
    {
        var sortProviderDictionary = new Dictionary<int, Func<SortOrder, IEnumerable<T>>>();
        var previousSortOrderDictionary = new Dictionary<int, SortOrder>();
        var itemType = typeof(T);
        dataGridView.DataSource = dataSource;
        foreach (DataGridViewColumn c in dataGridView.Columns)
        {
            object Provider(T info) => itemType.GetProperty(c.Name)?.GetValue(info);
            sortProviderDictionary[c.Index] = so => so != defaultSort ? 
                dataSource.OrderByDescending<T, object>(Provider) : 
                dataSource.OrderBy<T,object>(Provider);
            previousSortOrderDictionary[c.Index] = initialSort;
        }

        async Task DoSort(int index)
        {

            switch (previousSortOrderDictionary[index])
            {
                case SortOrder.Ascending:
                    previousSortOrderDictionary[index] = SortOrder.Descending;
                    break;
                case SortOrder.None:
                case SortOrder.Descending:
                    previousSortOrderDictionary[index] = SortOrder.Ascending;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            IEnumerable<T> sorted = null;
            dataGridView.Cursor = Cursors.WaitCursor;
            dataGridView.Enabled = false;
            await Task.Run(() => sorted = sortProviderDictionary[index](previousSortOrderDictionary[index]).ToList());
            dataGridView.DataSource = sorted;
            dataGridView.Enabled = true;
            dataGridView.Cursor = Cursors.Default;

        }

        dataGridView.ColumnHeaderMouseClick+= (object sender, DataGridViewCellMouseEventArgs e) => DoSort(index: e.ColumnIndex);
    }
}
0 голосов
/ 16 мая 2017

Я предлагаю использовать DataTable.DefaultView в качестве источника данных. Тогда строка ниже.

foreach (DataGridViewColumn column in gridview.Columns)
    {
       column.SortMode = DataGridViewColumnSortMode.Automatic;
    }

После этого само представление сетки будет управлять сортировкой (поддерживается Ascending или Descending.)

0 голосов
/ 18 июня 2014

У меня есть привязка объекта BindingList <> в качестве источника данных для dataGridView.

BindingList x1;
x1 = new BindingList<sourceObject>();
BindingSource bsx1 = new BindingSource();
bsx1.DataSource = x1;
dataGridView1.DataSource = bsx1;

Когда я щелкаю заголовок столбца, сортировка не происходит. Я использовал ответ SortableBindingList, предоставленный Томом Бушеллом. Включив два исходных файла в мой проект

  1. SortableBindingList.cs
  2. PropertyComparer.cs

Затем это изменение вносится в мой код:

Be.Timvw.Framework.ComponentModel.SortableBindingList x1;                       // 1
x1 = new Be.Timvw.Framework.ComponentModel.SortableBindingList<sourceObject>(); // 2
BindingSource bsx1 = new BindingSource();
bsx1.DataSource = x1;
dataGridView1.DataSource = bsx1;

После этих изменений я выполнил сборку своей программы. Теперь я могу сортировать, нажимая заголовки столбцов. Нужно изменить только две строки, они выделены в фрагменте кода выше завершающими комментариями.

0 голосов
/ 02 июля 2013

На всякий случай, если кто-то все еще ищет это, я сделал это на VS 2008 C #.

В Event ColumnHeaderMouseClick добавьте привязку данных для вида сетки и отправьте заказ по полю, как параметр. Вы можете получить щелкнутое поле следующим образом:

dgView.Columns[e.ColumnIndex].Name

В моем случае имена заголовков аналогичны именам полей просмотра.

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