Как сортировать datagridview на 2 столбца

Как отсортировать DataGridView по двум столбцам (по возрастанию)? У меня два столбца: day и status.

Если мне нужно сортировать по одному столбцу, я:

this.dataGridView1.Sort (this.dataGridView1.Columns["day"], ListSortDirection.Ascending);

Но для двух?

Ответ 1

Если ваш DataGridView является привязкой к базе данных, вы можете сортировать представление Datatable и перегруппировку в datatable, как показано ниже:

private DataGridView dataGridView1 = new DataGridView();
private BindingSource bindingSource1 = new BindingSource();

private void Form1_Load(object sender, System.EventArgs e)
{
    // Bind the DataGridView to the BindingSource        
    dataGridView1.DataSource = bindingSource1;
    SortDataByMultiColumns(); //Sort the Data
}

private void SortDataByMultiColumns()
{
    DataView view = dataTable1.DefaultView;
    view.Sort = "day ASC, status DESC"; 
    bindingSource1.DataSource = view; //rebind the data source
}

ИЛИ, без использования bindingsource и привязки непосредственно к DataView:

private void SortDataByMultiColumns()
{
    DataView view = ds.Tables[0].DefaultView;
    view.Sort = "day ASC, status DESC"; 
    dataGridView1.DataSource = view; //rebind the data source
}

Ответ 2

Добавьте скрытый столбец, который объединяет два и сортирует их.

Ответ 3

TL;DR; У меня есть двухстрочное решение.

Мне нужно было сделать то же самое, но после изучения всех этих сложных способов сделать это, включив отдельную DLL или написать собственный класс/методы, я знал, что должен быть более простой способ. Оказывается, я был прав, потому что я понял, как это сделать, используя только две строки кода. Это сработало для меня.

К счастью, нам оказывается, что метод .NET Framework Sort() помогает нам в этом. Идея состоит в том, что вы хотите сортировать столбцы по отдельности, но порядок, в котором вы их сортируете, - это то, что даст желаемый результат.

Итак, в качестве примера у меня есть столбец для типа файла и столбец для имени файла. Всякий раз, когда я хочу сортировать данные по типам, я хочу убедиться, что имена также сортируются в каждом показанном типе.

ЦЕЛЬ: Сортировка по типу также сортирует имена файлов по алфавиту.

Данные:

zxcv.css

testimg3.jpg

asdf.html

testimg2.jpg

testimg1.jpg

Сортировка данных по имени:

mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mNameLabel.Index], ListSortDirection.Ascending);

asdf.html

testimg1.jpg

testimg2.jpg

testimg3.jpg

zxcv.css

Как вы можете видеть, это будет означать, что имена будут отсортированы соответственно, так что, когда я теперь сортирую по типам файлов, оба требования будут удовлетворять.

Сортировка данных по типу файла:

mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mFileExtensionLabel.Index], ListSortDirection.Ascending);

zxcv.css

asdf.html

testimg1.jpg

testimg2.jpg

testimg3.jpg

Voila! Это отсортировано!

РЕШЕНИЕ: В вашем случае вы можете попробовать что-то вроде следующего, и вам может потребоваться настроить его еще немного, чтобы он мог использовать ваш собственный код.

DataGridView1.Sort(DataGridView1.Columns["status"], ListSortDirection.Ascending);
DataGridView1.Sort(DataGridView1.Columns["day"], ListSortDirection.Asscending);

Это должно быть способно отображать ваши результаты по дням, а также сортировать их поле статуса.

Ответ 4

Вы можете использовать метод сортировки DataGridView, но укажите аргумент, являющийся экземпляром класса, который реализует IComparer.

Вот пример такого класса:

public class MyTwoColumnComparer : System.Collections.IComparer
{
    private string _SortColumnName1;
    private int _SortOrderMultiplier1;
    private string _SortColumnName2;
    private int _SortOrderMultiplier2;

    public MyTwoColumnComparer(string pSortColumnName1, SortOrder pSortOrder1, string pSortColumnName2, SortOrder pSortOrder2)
    {
        _SortColumnName1 = pSortColumnName1;
        _SortOrderMultiplier1 = (pSortOrder1 == SortOrder.Ascending) ? 1 : -1;
        _SortColumnName2 = pSortColumnName2;
        _SortOrderMultiplier2 = (pSortOrder2 == SortOrder.Ascending) ? 1 : -1;
    }

    public int Compare(object x, object y)
    {
        DataGridViewRow r1 = (DataGridViewRow)x;
        DataGridViewRow r2 = (DataGridViewRow)y;

        int iCompareResult = _SortOrderMultiplier1 * String.Compare(r1.Cells[_SortColumnName1].Value.ToString(), r2.Cells[_SortColumnName1].Value.ToString());
        if (iCompareResult == 0) iCompareResult = _SortOrderMultiplier2 * String.Compare(r1.Cells[_SortColumnName2].Value.ToString(), r2.Cells[_SortColumnName2].Value.ToString());
        return iCompareResult;
    }
}

Теперь мы можем называть это из столбца, SortMode которого является "Programmatic" при щелчке мышью:

private void dgvAllMyEmployees_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    DataGridViewColumn dgvcClicked = dgvAllEmployees.Columns[e.ColumnIndex];
    if (dgvcClicked.SortMode == DataGridViewColumnSortMode.Programmatic)
    {
        _SortOrder = (_SortOrder == SortOrder.Ascending) ? SortOrder.Descending : SortOrder.Ascending;
        MyTwoColumnComparer Sort2C = new MyTwoColumnComparer(dgvcClicked.Name, _SortOrder, "LastName", SortOrder.Ascending);
        dgvAllEmployees.Sort(Sort2C);
    }
}

Переменная уровня класса _SortOrder помогает отслеживать, какой заказ входит. Можно увеличить это, чтобы запомнить последние два столбца, которые были нажаты и отсортированы по ним в нужном порядке.

Ответ 5

Вы можете попробовать this или использовать пользовательскую сортировку:

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (dataGridView1.Columns[e.ColumnIndex].HeaderText =="day")
            {
               myBindingSource.Sort = "day, hour";
            }
        }

Ответ 6

Ответ, который предоставил Джон Курц, заставил меня закрыть меня. Но я обнаружил, что когда я щелкнул по столбцу один раз, он действительно отсортировался по двум столбцам... В его примере: dgvcClicked.Name, "LastName". Итак, хорошо!

Но, если бы я снова щелкнул по столбцу, это НЕ будет сортироваться в противоположном направлении. Итак, столбец застрял в восходящем.

Чтобы преодолеть это, мне пришлось отслеживать порядок сортировки вручную. Начал с этого класса:

public class ColumnSorting
{
    public int ColumnIndex { get; set; }
    public ListSortDirection Direction { get; set; }
}

Затем я добавил этот список с глобальным охватом:

List<ColumnSorting> _columnSortingList = new List<ColumnSorting>();

Затем, в методе, который выполняет сортировку, я бы

  • Проверьте, существует ли отсортированный индекс столбца в _columnSortingList. Если нет, добавьте его.
  • Если он уже существует, замените порядок сортировки

И Боб твой дядя.