Сортировка ListView, используя столбец, который вы нажимаете на C#
Вы можете сортировать ListView с помощью столбца, который вы нажимаете, но это намного больше, чем просто сортировка элементов ListView. Для сортировки с использованием элементов вы можете просто установить свойство Sorting элемента управления в Ascending или Descending. К сожалению, элемент управления сортирует только его элементы, а не их подпозиции. (Он даже не будет использовать подпункты для разрыва связей, когда элементы имеют один и тот же текст.)
Чтобы изменить поведение сортировки элемента управления, вы должны создать класс, реализующий интерфейс IComparer. Ключом к этому классу является метод Compare. Этот метод принимает в качестве параметров два ListViewItems для сравнения и должен возвращать -1, если первый должен быть до второго в порядке сортировки, 0, если элементы равны, и 1, если первый элемент должен появиться после второй.
Следующий код показывает класс ListViewComparer, используемый в этом примере.
// Сравнивает два элемента ListView на основе выбранного столбца. public class ListViewComparer : System.Collections.IComparer { private int ColumnNumber; private SortOrder SortOrder; public ListViewComparer(int column_number, SortOrder sort_order) { ColumnNumber = column_number; SortOrder = sort_order; } // Сравнение двух списков ListViewItems. public int Compare(object object_x, object object_y) { // Получить объекты как ListViewItems. ListViewItem item_x = object_x as ListViewItem; ListViewItem item_y = object_y as ListViewItem; // Получаем соответствующие значения подпозиции. string string_x; if (item_x.SubItems.Count <= ColumnNumber) { string_x = ""; } else { string_x = item_x.SubItems[ColumnNumber].Text; } string string_y; if (item_y.SubItems.Count <= ColumnNumber) { string_y = ""; } else { string_y = item_y.SubItems[ColumnNumber].Text; } // Сравните их. int result; double double_x, double_y; if (double.TryParse(string_x, out double_x) && double.TryParse(string_y, out double_y)) { // Обрабатываем как число. result = double_x.CompareTo(double_y); } else { DateTime date_x, date_y; if (DateTime.TryParse(string_x, out date_x) && DateTime.TryParse(string_y, out date_y)) { // Обработать как дату. result = date_x.CompareTo(date_y); } else { // Обработать как строку. result = string_x.CompareTo(string_y); } } // Вернуть правильный результат в зависимости от того, // сортируем по возрастанию или по убыванию. if (SortOrder == SortOrder.Ascending) { return result; } else { return -result; } } }
Класс использует частные переменные ColumnNumber и SortOrder, чтобы отслеживать столбец, на котором он должен сортироваться, и должен ли он сортировать восходящий или нисходящий. Эти значения задаются конструктором класса.
Метод Compare сравнивает соответствующие подпункты, чтобы определить, как должны быть заказаны два элемента. Он должен сделать небольшую проверку, чтобы защититься от случая, когда у одного из элементов нет подэлемента, который объект пытается сравнить. (Например, если вы сравниваете четвертый подпункт, но один из элементов имеет только два подпункта.)
Код также пытается преобразовать значения в двойные и дат, чтобы увидеть, следует ли сортировать значения с использованием этих типов данных. Например, поскольку строки «9» появляются после «100», но как цифры 9 до 100. Аналогично, как строки «10/10/2010» предшествуют «1/1/2009», но по мере того, как даты 10/10/2010 появляются после 1/1/2009. Сравнение значений как чисел или дат делает их более разумными для пользователей.
В примерной программе используется следующий код для сортировки, когда вы нажимаете столбец ListView.
// Столбец, который мы сейчас используем для сортировки. private ColumnHeader SortingColumn = null; // Сортировка в этом столбце. private void lvwBooks_ColumnClick(object sender, ColumnClickEventArgs e) { // Получить новый столбец сортировки. ColumnHeader new_sorting_column = lvwBooks.Columns[e.Column]; // Извлеките новый порядок сортировки. System.Windows.Forms.SortOrder sort_order; if (SortingColumn == null) { // Новый столбец. Сортировать по возрастанию. sort_order = SortOrder.Ascending; } else { // См., Если это тот же самый столбец. if (new_sorting_column == SortingColumn) { // Тот же столбец. Переключите порядок сортировки. if (SortingColumn.Text.StartsWith("> ")) { sort_order = SortOrder.Descending; } else { sort_order = SortOrder.Ascending; } } else { // Новый столбец. Сортировать по возрастанию. sort_order = SortOrder.Ascending; } // Удаление старого индикатора сортировки. SortingColumn.Text = SortingColumn.Text.Substring(2); } // Отображение нового порядка сортировки. SortingColumn = new_sorting_column; if (sort_order == SortOrder.Ascending) { SortingColumn.Text = "> " + SortingColumn.Text; } else { SortingColumn.Text = "< " + SortingColumn.Text; } // Создаем компаратор. lvwBooks.ListViewItemSorter = new ListViewComparer(e.Column, sort_order); // Сортировать. lvwBooks.Sort(); }
Переменная SortingColumn отслеживает столбец, который в настоящее время сортирует программа.
Когда пользователь нажимает заголовок столбца, программа определяет, какой столбец был нажат. Затем он определяет новый порядок сортировки, который он должен использовать. Если новый столбец совпадает со старым, программа переключает порядок сортировки. В противном случае сортировка возрастает.
Программа добавляет «& gt;» к заголовку столбца, когда сортирует по возрастанию и «& lt;» при сортировке по убыванию. Он использует эти символы для определения текущего порядка сортировки.
После принятия решения о новом порядке сортировки программа удаляет индикатор сортировки ("& gt;" или "& lt;") из текущего столбца сортировки и добавляет его в новый столбец сортировки.