简体   繁体   English

如何更快地对ListView排序?

[英]How to Sort a ListView Faster?

I have found a solution in MSDN for ListView sorting... But I found the code to be taking too much time to display the ListView properly when a column is clicked... So I am asking for a solution to speed it up. 我在MSDN中找到了一种用于ListView排序的解决方案...但是,我发现代码在单击列时花了太多时间才能正确显示ListView ...因此,我想寻求一种解决方案以加快其速度。 I have to sort a ListView containing more than 10,000 items. 我必须对包含超过10,000个项目的ListView进行排序。 Here is my whole code... 这是我的整个代码...


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Runtime.InteropServices;

namespace ListViewSorter
{
    class ListViewSorter
    {
        const Int32 HDF_SORTDOWN = 0x200;
        const Int32 HDF_SORTUP = 0x400;
        const Int32 HDI_FORMAT = 0x4;
        const Int32 HDM_GETITEM = 0x120b;
        const Int32 HDM_SETITEM = 0x120c;
        const Int32 LVM_GETHEADER = 0x101f;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        static extern IntPtr SendMessageLVCOLUMN(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref LVCOLUMN lParam);

        [StructLayout(LayoutKind.Sequential)]
        public struct LVCOLUMN
        {
            public Int32 mask;
            public Int32 cx;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string pszText;
            public IntPtr hbm;
            public Int32 cchTextMax;
            public Int32 fmt;
            public Int32 iSubItem;
            public Int32 iImage;
            public Int32 iOrder;
        }
        public void SetSortIcon( ListView listview, int ColumnIndex)
        {
            IntPtr clmHdr = SendMessage(listview.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
            SortOrder sorting = listview.Sorting;
            for (int i = 0; i < listview.Columns.Count; i++)
            {
                IntPtr clmPtr = new IntPtr(i);
                LVCOLUMN lvColumn = new LVCOLUMN();

                lvColumn.mask = HDI_FORMAT;
                SendMessageLVCOLUMN(clmHdr, HDM_GETITEM, clmPtr, ref lvColumn);
                if (sorting != SortOrder.None && i == ColumnIndex)
                {
                    if (sorting == SortOrder.Ascending)
                    {
                        lvColumn.fmt &= ~HDF_SORTDOWN;
                        lvColumn.fmt |= HDF_SORTUP;
                    }
                    else
                    {
                        lvColumn.fmt &= ~HDF_SORTUP;
                        lvColumn.fmt |= HDF_SORTDOWN;
                    }
                }
                else
                {
                    lvColumn.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP;
                }
                SendMessageLVCOLUMN(clmHdr, HDM_SETITEM, clmPtr, ref lvColumn);
            }
        }
        public int SortColumn(ListView listview, int ColumnIndex, int sortColumn)
        {
            if (ColumnIndex != sortColumn)
            {
                sortColumn = ColumnIndex;
                listview.Sorting = SortOrder.Ascending;
            }
            else
            {
                if (listview.Sorting == SortOrder.Ascending)
                    listview.Sorting = SortOrder.Descending;
                else
                    listview.Sorting = SortOrder.Ascending;
            }
            SetSortIcon(listview, sortColumn);
            listview.Sort();
            listview.ListViewItemSorter = new ListViewItemComparer(ColumnIndex,
                                                              listview.Sorting);
            return sortColumn;
        }
    }
    class ListViewItemComparer : IComparer
    {
        private int col;
        private SortOrder order;
        public ListViewItemComparer()
        {
            col = 0;
            order = SortOrder.Ascending;
        }
        public ListViewItemComparer(int column, SortOrder order)
        {
            col = column;
            this.order = order;
        }
        public int Compare(object x, object y)
        {
            int returnVal;
            try
            {
                System.DateTime firstDate =
                        DateTime.Parse(((ListViewItem)x).SubItems[col].Text);
                System.DateTime secondDate =
                        DateTime.Parse(((ListViewItem)y).SubItems[col].Text);
                returnVal = DateTime.Compare(firstDate, secondDate);
            }
            catch
            {
                returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
                            ((ListViewItem)y).SubItems[col].Text);
            }
            if (order == SortOrder.Descending)
                returnVal *= -1;
            return returnVal;
        }

    }
}

Can anyone help me out of this problem? 谁能帮我解决这个问题?

One of the ways that comes in my mind now is use od data-binding and set VirtualMode http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode.aspx . 我现在想到的一种方法是使用od data-binding并设置VirtualMode http://msdn.microsoft.com/zh-cn/library/system.windows.forms.listview.virtualmode.aspx Property to true . 属性为true

Doing so you wil achieve foliwing: 这样一来,您就可以实现以下目标:

  • your big custom data data-layer custom management. 您的大自定义数据data-layer自定义管理。 In other words you make a sort on data and bind it to listview and not sorting listview items. 换句话说,您对数据进行排序并将其绑定到listview而不是对listview项进行排序。

  • listView.VirtualMode=true; will force listview control to create listview items only for that items that are visible in ui . 将强制listview控件仅为ui中可见的项目创建listview项 In other words, if you have 10.000 items in datacollection but on UI I can se only 15 of them, due the window dimension, the rendering and lustviewitem ui artifact creation time will be spend only for 15 and not for 10.000 like it does in your case. 换句话说,如果您在datacollection有10.000个项目,但是在UI上我只能识别其中的15个项目,那么由于窗口尺寸, 渲染和lustviewitem ui工件创建时间将只花费15个而不是10.000个,就像在您的项目中那样案件。

Hope this helps. 希望这可以帮助。

I think you should try defining the datatypes instead of using object. 我认为您应该尝试定义数据类型而不是使用对象。 Forcing the complier to figure out the dt's takes extra time. 强迫编译器找出dt会花费额外的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM