Как я могу отсортировать WinForms DataGridView в столбце CheckBox?

Итак, у меня был DataGridView с автоматически сгенерированными столбцами, некоторые из которых были столбцами флажков. Когда я нажал на заголовок столбца флажка, он не сортировался. Я исследовал это, и оказалось, что Microsoft не включила автоматическую сортировку для столбцов флажков... Что я считаю абсурдным - насколько сложно сортировать проверено / не проверено?

Как вы можете получить DataGridView сортировать столбцы флажков для вас?

Вот что я придумал:

5 ответов

Решение

Сначала нужно подключить два события: событие добавления столбца и событие щелчка заголовка столбца:

AddHandler dg.ColumnAdded, AddressOf dgColumnAdded
AddHandler dg.ColumnHeaderMouseClick, AddressOf dgSortColumns

Затем включите программную сортировку для каждого столбца флажка:

Private Sub dgColumnAdded(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewColumnEventArgs)
    If e.Column.GetType Is GetType(DataGridViewCheckBoxColumn) Then
        e.Column.SortMode = DataGridViewColumnSortMode.Programmatic
    End If
End Sub

Затем создайте обработчик, который будет сортировать столбец флажка, но ничего не делать для столбцов, которые будут обрабатывать свою собственную сортировку:

Private Sub dgSortColumns(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs)
    Dim dg As DataGridView = sender
    Dim c As DataGridViewColumn = dg.Columns(e.ColumnIndex)
    If c.SortMode = DataGridViewColumnSortMode.Programmatic Then
        If dg.SortedColumn IsNot Nothing _
        AndAlso dg.SortedColumn.Name <> c.Name Then
            dg.Sort(c, System.ComponentModel.ListSortDirection.Ascending)
        Else
            Select Case dg.SortOrder
                Case Windows.Forms.SortOrder.None
                    dg.Sort(c, System.ComponentModel.ListSortDirection.Ascending)
                Case Windows.Forms.SortOrder.Ascending
                    dg.Sort(c, System.ComponentModel.ListSortDirection.Descending)
                Case Windows.Forms.SortOrder.Descending
                    dg.Sort(c, System.ComponentModel.ListSortDirection.Ascending)
            End Select
        End If
    End If
End Sub

И вот, пожалуйста! Было ли это действительно так сложно, Microsoft?;-)

Вы также можете просто сделать это:

DataGridView.Columns("ColumnOfChoice").SortMode = DataGridViewColumnSortMode.Automatic

Работает в vb.net 4.0

Вам нужно только добавить следующие строки в код формы (протестировано в VB.NET 2013)

Private Sub DataGridView1_ColumnAdded(sender As Object, e As System.Windows.Forms.DataGridViewColumnEventArgs) Handles DataGridView1.ColumnAdded
    If e.Column.GetType Is GetType(DataGridViewCheckBoxColumn) Then
        e.Column.SortMode = DataGridViewColumnSortMode.Automatic
    End If
End Sub

Я не уверен насчет VB, но для C# в VS2012 в конструкторе вы также можете установить SortMode.

Щелкните правой кнопкой мыши DataGridView и перейдите к "Редактировать столбцы".

В SortMode есть раскрывающийся список с вариантами NotSortable, Automatic и Programmatic.

Похоже, что по умолчанию для большинства столбцов установлено значение Автоматически, но для столбцов с флажками (логические значения) по умолчанию установлено значение NotSortable.

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

------ Убедитесь, что ваш источник данных является сортируемым. ------

Если вы связываете DataGridView с простым List it WYT WORK, вам нужно использовать что-то другое, я рекомендую вам использовать этот SortableBindingList; Вы можете напрямую передать исходный List IEnumerable в конструктор SortableBindingList.

Нагрузка:

private void frmWithTheDataGrid_Load(object sender, EventArgs e)
{
    this.yourDataGridView.SortabilizeMe();
}

Затем добавьте это в статический класс, чтобы использовать его как ExtensionMethod.

public static void SortabilizeMe(this DataGridView dgv)
{
    dgv.ColumnAdded+= delegate(object sender, DataGridViewColumnEventArgs args)
    {
        args.Column.SortMode = DataGridViewColumnSortMode.Programmatic;
    };

    dgv.ColumnHeaderMouseClick += delegate(object sender, DataGridViewCellMouseEventArgs args)
    {
        var col = dgv.Columns[args.ColumnIndex];

        if (dgv.SortedColumn != null && dgv.SortedColumn.Name != col.Name)
        {
            dgv.Sort(row, ListSortDirection.Ascending);
        }
        else
        {
            switch (dgv.SortOrder)
            {
                case SortOrder.None:
                    dgv.Sort(col, ListSortDirection.Ascending);
                    break;
                case SortOrder.Ascending:
                    dgv.Sort(col, ListSortDirection.Descending);
                    break;
                case SortOrder.Descending:
                    dgv.Sort(col, ListSortDirection.Ascending);
                    break;
            }
        }
    };
}

Тогда волшебство случится:)

Другие вопросы по тегам