List <> OrderBy IComparer?

2

У меня есть 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();
    }
}

но ничего не происходит! Я ожидаю, что хотя бы исключение было броском!
Не могли бы вы направить меня?
Спасибо.

  • 2
    Как вы ожидаете увидеть исключение, если оно было сгенерировано, когда вы просто «съели» исключение (отсюда и пустой улов).
  • 0
    Я добавил точку останова
Теги:
linq
list
sql-order-by

2 ответа

4
Лучший ответ

Методы LINQ не влияют на коллекцию, они возвращают новую коллекцию. Вы можете использовать метод ToList, чтобы преобразовать результат в список и назначить его обратно в переменную списка:

this.ListOfItems = this.ListOfItems.OrderBy(a => a, new CompareListItemsClass(e.Column, lvwColumnSorter.Order)).ToList();
4

Методы расширения 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);
  • 0
    Не могли бы вы опубликовать пример кода для сортировки по убыванию и возрастанию с List <T>. Сортировать?
  • 0
    Спасибо Томас Левеск

Ещё вопросы

Сообщество Overcoder
Наверх
Меню