Как сортировать ListView быстрее? - PullRequest
0 голосов
/ 28 декабря 2011

Я нашел решение в MSDN для сортировки ListView ... Но я обнаружил, что код занимает слишком много времени для правильного отображения ListView при нажатии на столбец ... Поэтому я прошу решение, чтобы ускорить его. Я должен отсортировать ListView, содержащий более 10000 элементов. Вот весь мой код ...


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;
        }

    }
}

Может кто-нибудь помочь мне выйти из этой проблемы?

Ответы [ 2 ]

1 голос
/ 28 декабря 2011

Один из способов, который приходит мне в голову, - это использовать od data-binding и установить для свойства VirtualMode http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode.aspx. значение true.

Делая так, вы достигнете следующего:

  • ваши большие пользовательские данные data-layer настраиваемое управление.Другими словами, вы производите сортировку по данным и привязываете к listview, а не сортируете listview элементов.

  • listView.VirtualMode=true; заставит listviewуправляйте для создания элементов списка только для тех элементов, которые видны в пользовательском интерфейсе .Другими словами, если у вас есть 10.000 элементов в datacollection, но в пользовательском интерфейсе я могу выбрать только 15 из них, из-за размера окна, рендеринга и lustviewitem артефакта пользовательского интерфейса время будет потрачено только на 15 ине на 10.000, как в вашем случае.

Надеюсь, это поможет.

0 голосов
/ 28 декабря 2011

Я думаю, вы должны попытаться определить типы данных вместо использования объекта. Заставление компилятора выяснить dt требует дополнительного времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...