按列对ListView排序

Mik*_*ike 18 c# sorting listview

目前我在listview上使用自定义排序器,每次单击FIRST列时我都可以对listview进行排序,但不会按其他列排序.

SortStyle:变量,用于确定它是Ascending Sort还是Descending.

if (e.Column == 0)
{
    if (SortStyle == 0)
    {
        List.ListViewItemSorter = customSortDsc;
        SortStyle = 1;
    }
    else
    {
        List.ListViewItemSorter = customSortAsc;
        SortStyle = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

在为第一列排序时,这可以正常工作,但如果您要在任何其他列上执行此操作,它将只按第一列排序.有没有办法按列点击排序?

Red*_*Eye 23

忘掉你的自定义分拣机.重新开始使用下一页的代码.它将向您展示如何定义从IComparer接口继承的类.每行都已注释掉,因此您可以实际查看正在发生的事情.唯一可能的复杂因素是如何从Listview控件中检索Listview项.得到那些平方,你需要做的就是复制并粘贴IComparer接口类和columnClick方法.

http://support.microsoft.com/kb/319401

  • 非常有用的链接.似乎是最简单的解决方案.谢谢RedEye. (2认同)
  • 或者更好的是,使用上面链接的代码创建您自己的 SortableListView 然后您需要更改的只是您的列表被初始化的一行。 (2认同)
  • 由于事件接收器中的代码是非常标准的行为,我在**ListViewColumnSorter**类中添加了**ReverseSortOrderAndSort(int column,ListView lv)**方法,因此事件接收器中的代码变为:private void listView1_ColumnClick(object sender,ColumnClickEventArgs e){listViewColumnSorter.ReverseSortOrderAndSort(e.Column,(ListView)sender); } (2认同)

Gra*_*ian 20

如果您开始使用ListView,请自己做一个大忙,并使用ObjectListView.ObjectListView是.NET WinForms ListView的开源包装器,它使ListView更易于使用,并为您解决了许多常见问题.按列排序是自动处理的众多内容之一.

说真的,你永远不会后悔使用ObjectListView而不是普通的ListView.

  • 我之前使用过ObjectListView并喜欢它.您必须注意的一件事是它是GPL,因此您可能必须发布源代码. (13认同)
  • 我知道这是一个旧帖子,但是这个FAQ链接声明它在GPLv3下列出并且无法在封闭的源应用程序中重新分发是不正确的.如果它是GPLv3,那么毫无疑问你可以在商业软件中使用它.我不关心开发人员常见问题解答说什么,如果他不研究他的许可并称之为GPLv3应用程序,只要他们遵循GPL条款,他就没有任何立场(IMO)对使用他的软件的企业站立起来.他们需要分发组件(而不是整个应用程序)的代码(或链接)以及GPL的副本www.gnu.org/licenses/gpl.html,请参阅第4,5和6节 (3认同)
  • @AdamPlocher我用了一个网站来快速总结不同的许可证,最近他们找了一位律师来确认许可证的摘要,[根据他们的总结](https://tldrlegal.com/license/gnu-general-public -license-v3-(gpl-3)):"所有与GPL 3.0源代码链接的代码必须在GPL 3.0兼容许可下公开.",这意味着如果您将其用作依赖项,则必须发布您的完整源代码.应用 (3认同)
  • 这不是 ObjectListView FAQ 所说的。您关于 GPL 的陈述与普遍理解的解释相反,例如 http://programmers.stackexchange.com/questions/158789/can-i-link-to-a-gpl-library-from-a-closed-source-应用。 (2认同)

Wil*_*l P 6

我使用列名来排序,根据存储在列中的数据类型设置可能需要处理的任何排序细节,或者如果列已经排序(asc/desc).这是我的ColumnClick事件处理程序的片段.

private void listView_ColumnClick(object sender, ColumnClickEventArgs e)
    {
        ListViewItemComparer sorter = GetListViewSorter(e.Column);

        listView.ListViewItemSorter = sorter;
        listView.Sort();
    }

    private ListViewItemComparer GetListViewSorter(int columnIndex)
    {
        ListViewItemComparer sorter = (ListViewItemComparer)listView.ListViewItemSorter;
        if (sorter == null)
        {
            sorter = new ListViewItemComparer();
        }

        sorter.ColumnIndex = columnIndex;

        string columnName = packagedEstimateListView.Columns[columnIndex].Name;
        switch (columnName)
        {
            case ApplicationModel.DisplayColumns.DateCreated:
            case ApplicationModel.DisplayColumns.DateUpdated:
                sorter.ColumnType = ColumnDataType.DateTime;
                break;
            case ApplicationModel.DisplayColumns.NetTotal:
            case ApplicationModel.DisplayColumns.GrossTotal:
                sorter.ColumnType = ColumnDataType.Decimal;
                break;
            default:
                sorter.ColumnType = ColumnDataType.String;
                break;
        }

        if (sorter.SortDirection == SortOrder.Ascending)
        {
            sorter.SortDirection = SortOrder.Descending;
        }
        else
        {
            sorter.SortDirection = SortOrder.Ascending;
        }

        return sorter;
    }
Run Code Online (Sandbox Code Playgroud)

下面是我的ListViewItemComparer

public class ListViewItemComparer : IComparer
{
    private int _columnIndex;
    public int ColumnIndex
    {
        get
        {
            return _columnIndex;
        }
        set
        {
            _columnIndex = value;
        }
    }

    private SortOrder _sortDirection;
    public SortOrder SortDirection
    {
        get
        {
            return _sortDirection;
        }
        set
        {
            _sortDirection = value;
        }
    }

    private ColumnDataType _columnType;
    public ColumnDataType ColumnType
    {
        get
        {
            return _columnType;
        }
        set
        {
            _columnType = value;
        }
    }


    public ListViewItemComparer()
    {
        _sortDirection = SortOrder.None;
    }

    public int Compare(object x, object y)
    {
        ListViewItem lviX = x as ListViewItem;
        ListViewItem lviY = y as ListViewItem;

        int result;

        if (lviX == null && lviY == null)
        {
            result = 0;
        }
        else if (lviX == null)
        {
            result = -1;
        }

        else if (lviY == null)
        {
            result = 1;
        }

        switch (ColumnType)
        {
            case ColumnDataType.DateTime:
                DateTime xDt = DataParseUtility.ParseDate(lviX.SubItems[ColumnIndex].Text);
                DateTime yDt = DataParseUtility.ParseDate(lviY.SubItems[ColumnIndex].Text);
                result = DateTime.Compare(xDt, yDt);
                break;

            case ColumnDataType.Decimal:
                Decimal xD = DataParseUtility.ParseDecimal(lviX.SubItems[ColumnIndex].Text.Replace("$", string.Empty).Replace(",", string.Empty));
                Decimal yD = DataParseUtility.ParseDecimal(lviY.SubItems[ColumnIndex].Text.Replace("$", string.Empty).Replace(",", string.Empty));
                result = Decimal.Compare(xD, yD);
                break;
            case ColumnDataType.Short:
                short xShort = DataParseUtility.ParseShort(lviX.SubItems[ColumnIndex].Text);
                short yShort = DataParseUtility.ParseShort(lviY.SubItems[ColumnIndex].Text);
                result = xShort.CompareTo(yShort);
                break;
            case ColumnDataType.Int:
                int xInt = DataParseUtility.ParseInt(lviX.SubItems[ColumnIndex].Text);
                int yInt = DataParseUtility.ParseInt(lviY.SubItems[ColumnIndex].Text);
                return xInt.CompareTo(yInt);
                break;
            case ColumnDataType.Long:
                long xLong = DataParseUtility.ParseLong(lviX.SubItems[ColumnIndex].Text);
                long yLong = DataParseUtility.ParseLong(lviY.SubItems[ColumnIndex].Text);
                return xLong.CompareTo(yLong);
                break;
            default:

                result = string.Compare(
                    lviX.SubItems[ColumnIndex].Text,
                    lviY.SubItems[ColumnIndex].Text,
                    false);

                break;
        }

        if (SortDirection == SortOrder.Descending)
        {
            return -result;
        }
        else
        {
            return result;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)