2011-12-28 13 views
0

MSDNのListViewソート用の解決策を見つけました... しかし、列がクリックされたときにListViewを正しく表示するには、コードが長すぎます... 速度を上げるためのソリューションを求めていますそれをアップ。私は10,000以上の項目を含むリストビューをソートする必要があります。ここに私のコード全体...
リストビューをより迅速に並べ替えるには?


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

    } 
} 

は、誰もがこの問題の私を助けることができるのですか?

答えて

1

ここで私の頭に浮かぶのは、data-bindingを使用し、VirtualModehttp://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode.aspxと設定します。プロパティはtrueです。

  • あなたの大切なカスタムデータdata-layerカスタム管理:

    あなたがfoliwingを達成ウィルそう。つまり、データにソートし、listviewにバインドし、listviewアイテムをソートしないでください。

  • listView.VirtualMode=true;のみUIに表示されているアイテムのリストビュー項目を作成するlistview制御を強制します。言い換えれば、datacollectionに10.000のアイテムがありますが、そのUIのうち15個しか表示できない場合は、レンダリングとlustviewitem uiアーティファクトの作成時間は15時間で、10.000時間ではなくなりますあなたの場合。

は、この情報がお役に立てば幸いです。

+0

私はまだ仮想モードでデータバインディングを使用する方法を少しヒントが必要です...実際には私はデータバインディングについて理解していません.. – Writwick

+1

@writz:これは参考になるhttp://www.codeproject.com/ KB/list/ListView_DataBinding.aspx – Tigran

+0

[BindableListViewコントロール](http://www.interact-sw.co.uk/utilities/bindablelistview/)が見つかりました...うまくいくのでしょうか?[私は実際にそこにコードを見つける] – Writwick

0

オブジェクトを使用する代わりにデータ型を定義してみるべきだと思います。コンパイラーにdtを把握させるために余分な時間がかかります。

関連する問題