[英]How to Sort a ListView Faster?
我在MSDN中找到了一种用于ListView排序的解决方案...但是,我发现代码在单击列时花了太多时间才能正确显示ListView ...因此,我想寻求一种解决方案以加快其速度。 我必须对包含超过10,000个项目的ListView进行排序。 这是我的整个代码...
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;
}
}
}
谁能帮我解决这个问题?
我现在想到的一种方法是使用od data-binding
并设置VirtualMode
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.listview.virtualmode.aspx 。 属性为true
。
这样一来,您就可以实现以下目标:
您的大自定义数据data-layer
自定义管理。 换句话说,您对数据进行排序并将其绑定到listview
而不是对listview
项进行排序。
listView.VirtualMode=true;
将强制listview
控件仅为ui中可见的项目创建listview项 。 换句话说,如果您在datacollection
有10.000个项目,但是在UI上我只能识别其中的15个项目,那么由于窗口尺寸, 渲染和lustviewitem ui工件创建时间将只花费15个而不是10.000个,就像在您的项目中那样案件。
希望这可以帮助。
我认为您应该尝试定义数据类型而不是使用对象。 强迫编译器找出dt会花费额外的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.