У меня есть List<ListViewItem>
, и я использовал его в ListView в VirtualMode
В списке 5000 элементов, и я собираюсь сортировать их с помощью LINQ и OrderBy всякий раз, когда нажимается Column of ListView, поэтому я написал код ниже:
List<ListViewItem> ListOfItems = new List<ListViewItem>();
ListViewColumnSorter lvwColumnSorter;
void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
try
{
// Determine if clicked column is already the column that is being sorted.
if (e.Column == lvwColumnSorter.SortColumn)
{
// Reverse the current sort direction for this column.
if (lvwColumnSorter.Order == SortOrder.Ascending)
{
lvwColumnSorter.Order = SortOrder.Descending;
}
else
{
lvwColumnSorter.Order = SortOrder.Ascending;
}
}
else
{
// Set the column number that is to be sorted; default to ascending.
lvwColumnSorter.SortColumn = e.Column;
lvwColumnSorter.Order = SortOrder.Ascending;
}
if (lvwColumnSorter.Order == SortOrder.Descending)
this.ListOfItems.OrderByDescending(a => a, new CompareListItemsClass(e.Column, lvwColumnSorter.Order));
else
this.ListOfItems.OrderBy(a => a, new CompareListItemsClass(e.Column, lvwColumnSorter.Order));
this.listView1.VirtualListSize = ListOfItems.Count;
this.listView1.Refresh();
}
catch { }
}
public class CompareListItemsClass : IComparer<ListViewItem>
{
private CaseInsensitiveComparer ObjectCompare = new CaseInsensitiveComparer();
private SortOrder OrderOfSort;
private int ColumnToSort;
public CompareListItemsClass(int columnIndex, SortOrder sortOrder)
{
ColumnToSort = columnIndex;
OrderOfSort = sortOrder;
}
public int Compare(ListViewItem listviewX, ListViewItem listviewY)
{
// Compare the two items
try
{
compareResult = ObjectCompare.Compare(
int.Parse(listviewX.SubItems[ColumnToSort].Text),
int.Parse(listviewY.SubItems[ColumnToSort].Text));
}
catch
{
compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text,
listviewY.SubItems[ColumnToSort].Text);
}
// Calculate correct return value based on object comparison
if (OrderOfSort == SortOrder.Ascending)
{
// Ascending sort is selected, return normal result of compare operation
return compareResult;
}
else if (OrderOfSort == SortOrder.Descending)
{
// Descending sort is selected, return negative result of compare operation
return (-compareResult);
}
else
{
// Return '0' to indicate they are equal
return 0;
}
}
int IComparer<ListViewItem>.Compare(ListViewItem x, ListViewItem y)
{
throw new NotImplementedException();
}
}
но ничего не происходит! Я ожидаю, что хотя бы исключение было броском!
Не могли бы вы направить меня?
Спасибо.
Методы LINQ не влияют на коллекцию, они возвращают новую коллекцию. Вы можете использовать метод ToList
, чтобы преобразовать результат в список и назначить его обратно в переменную списка:
this.ListOfItems = this.ListOfItems.OrderBy(a => a, new CompareListItemsClass(e.Column, lvwColumnSorter.Order)).ToList();
Методы расширения OrderBy
и OrderByDescending
не изменяют коллекцию, они возвращают последовательность элементов коллекции в указанном порядке. В вашем коде вы просто отбрасываете результат этих методов, поэтому ничего не происходит...
Если вам нужно отсортировать коллекцию "на месте" (т.е. изменить фактический порядок элементов), используйте List<T>.Sort
метод.
ИЗМЕНИТЬ
Чтобы реализовать нисходящий и восходящий порядок, на самом деле проще сделать это с помощью Comparison<T>
, чем с IComparer<T>
, так как вам просто нужно свести на нет результат... Вот пример:
Comparison<ListViewItem> temp = (x, y) =>
{
int xvalue = int.Parse(x.SubItems[e.Column].Text);
int yvalue = int.Parse(y.SubItems[e.Column].Text);
return xvalue.CompareTo(yvalue);
};
Comparison<ListViewItem> comparison;
if (lvwColumnSorter.Order == SortOrder.Ascending)
{
comparison = temp;
}
else
{
comparison = (x, y) => -temp(x, y);
}
this.ListOfItems.Sort(comparison);