2012-02-24 73 views
1

我想排序ListView其中也有一個DateTime列。這是我使用的代碼:我的C#ListView比較函數太慢

public bool isDate(Object obj) 
{ 
    string strDate = obj.ToString(); 
    try 
    { 
     DateTime dt = DateTime.Parse(strDate); 
     if (dt != DateTime.MinValue && dt != DateTime.MaxValue) 
      return true; 
     return false; 
    } 
    catch 
    { 
     return false; 
    } 
} 

public int Compare(object o1, object o2) 
{ 
    if (!(o1 is ListViewItem)) 
     return (0); 
    if (!(o2 is ListViewItem)) 
     return (0); 

    ListViewItem lvi1 = (ListViewItem)o2; 
    string str1 = lvi1.SubItems[ByColumn].Text; 
    ListViewItem lvi2 = (ListViewItem)o1; 
    string str2 = lvi2.SubItems[ByColumn].Text; 

    int result; 
    if (lvi1.ListView.Sorting == SortOrder.Ascending) 
    { 
     if (isDate(str1) && isDate(str2)) 
      result = DateTime.Compare(DateTime.Parse(str1), DateTime.Parse(str2)); 
     else 
      result = String.Compare(str1, str2); 
    } 
    else 
     result = String.Compare(str2, str1); 

    LastSort = ByColumn; 
    return result; 
} 

ListView持有約2000項,問題是,這是非常緩慢的。我究竟做錯了什麼?有任何想法嗎?

在此先感謝!

編輯:非常感謝。我是新手,現在是我的代碼。它快得多,我確定了我的邏輯。

public int Compare(object o1, object o2) 
{ 
    var lvi1 = o2 as ListViewItem; 
    var lvi2 = o1 as ListViewItem; 
    if (lvi1 == null || lvi2 == null) 
     return 0; 

    string str1 = lvi1.SubItems[ByColumn].Text; 
    string str2 = lvi2.SubItems[ByColumn].Text; 

    int result; 
    DateTime dateValue1 = new DateTime(); 
    DateTime dateValue2 = new DateTime(); 

    if (lvi1.ListView.Sorting == SortOrder.Ascending) 
    { 
     if (DateTime.TryParse(str1, out dateValue1) && DateTime.TryParse(str2, out dateValue2)) 
      result = DateTime.Compare(dateValue1, dateValue2); 
     else 
      result = String.Compare(str1, str2); 
    } 
    else 
    { 
     if (DateTime.TryParse(str1, out dateValue1) && DateTime.TryParse(str2, out dateValue2)) 
      result = DateTime.Compare(dateValue2, dateValue1); 
     else 
      result = String.Compare(str2, str1); 
    } 

    LastSort = ByColumn; 
    return result; 
} 
+0

這是使用WPF?如果是這樣,你能標記它嗎? – mindandmedia 2012-02-24 23:59:38

+2

爲什麼不使用'DateTime.TryParse()'而不是捕獲解析異常?它返回一個'bool',並使用一個輸出參數來設置成功的值。 – 2012-02-25 00:02:46

+1

另外我認爲你的邏輯有問題,當排序順序是升序時,你關心的是DateTime字段,但在其他情況下(降序)你不關心這個問題。 – 2012-02-25 00:04:08

回答

1

一些優化來在我的腦海:

  1. 相反而isDate使用:DateTime.TryParse
  2. 而不是做兩個時間鑄造:

    if (!(o1 is ListViewItem)) return (0);

    ListViewItem lvi1 = (ListViewItem)o2;

使用一次性鑄造:

var lvi1 = o2 as ListViewItem; 
if (lvi1 == null) 
    return 0; 

此外,我建議檢查你的代碼邏輯(正如我在評論中提及)。

+0

謝謝。我將它改爲TryParse,我想我修正了邏輯。 – pelz 2012-02-25 00:32:48

1

你不能只將ListViewItem.Tag設置爲DateTime嗎?然後比較日期時間:

DateTime d = (DateTime)ListViewItem.Tag; 
+0

我同意這個建議,這將避免從字符串到'DateTime'的所有轉換,這些轉換會在兩次(在isDate()內部),然後在比較'Compare()'中的兩個DateTime值時進行。如果'Tag'爲null,那麼你仍然可以回退到像你原來的邏輯正在做的字符串比較。 – 2012-02-25 00:31:08