Как сортировать 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. Если нет, добавьте его.
- Если он уже существует, замените порядок сортировки
И Боб твой дядя.