列表与LT;>订购IComparer?

时间:2010-01-16 22:01:13

标签: c# .net linq list sql-order-by

我有一个List<ListViewItem>,我在VirtualMode的ListView中使用过它 列表中有5000个项目,只要单击ListView的列,我就会用LINQ和OrderBy对它进行排序,所以我写了下面的代码:


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 :(得分:4)

OrderByOrderByDescending扩展方法不会修改集合,它们会按指定的顺序返回集合的一系列项目。在您的代码中,您只是丢弃这些方法的结果,因此没有任何反应......

如果您需要“就地”对集合进行排序(即修改项目的实际顺序),请使用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);

答案 1 :(得分:4)

LINQ方法不会影响集合,它们会返回一个新集合。您可以使用ToList方法将结果转换为列表并将其分配回列表变量:

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