2009-10-23 75 views
1

在控件ObjectListView(http://objectlistview.sourceforge.net/html/cookbook.htm)中,我試圖添加自定義排序器,忽略「The」和「A」前綴。ObjectListView:自定義排序器

我設法做到了這一點與常規的ListView,但現在我切換到ObjectListView(更多的功能,和緩解),我似乎無法做到這一點。

以下是在ObjectListView代碼我認爲主要比較器...

public int Compare(object x, object y) 
    { 
     return this.Compare((OLVListItem)x, (OLVListItem)y); 
    } 

原始排列爲升序,作爲一個例子(忽略 「A」 和 「該」)

public class CustomSortAsc : IComparer 
     { 
      int IComparer.Compare(Object x, Object y) 
      { 
       string[] px = Convert.ToString(x).Split(' '); 
       string[] py = Convert.ToString(y).Split(' '); 
       string newX = ""; 
       string newY = ""; 

       for (int i = 0; i < px.Length; i++) 
       { 
        px[i] = px[i].Replace("{", ""); 
        px[i] = px[i].Replace("}", ""); 
       } 
       for (int i = 0; i < py.Length; i++) 
       { 
        py[i] = py[i].Replace("{", ""); 
        py[i] = py[i].Replace("}", ""); 
       } 

       if ((px[1].ToLower() == "a") || (px[1].ToLower() == "the")) 
       { 
        if (px.Length > 1) 
        { 
         for (int i = 2; i < px.Length; i++) 
          newX += px[i]; 
        } 
       } 
       else 
       { 
        for (int i = 1; i < px.Length; i++) 
         newX += px[i]; 
       } 

       if ((py[1].ToLower() == "a") || (py[1].ToLower() == "the")) 
       { 
        if (py.Length > 1) 
        { 
         for (int i = 2; i < py.Length; i++) 
          newY += py[i]; 
        } 
       } 
       else 
       { 
        for (int i = 1; i < py.Length; i++) 
         newY += py[i]; 
       } 


       return ((new CaseInsensitiveComparer()).Compare(newX, newY)); 
      } 
+0

你可以添加更多的信息,比如你會得到什麼樣的結果,你如何用列表視圖等連接CustomSortAsc? – Ludovic 2009-10-23 20:55:10

回答

1

安裝CustomSorter代表,並且在該委託,把一個ListItemSorter到ObjectListView

this.incidentListView.CustomSorter = delegate(OLVColumn column, SortOrder order) { 
    this.incidentListView.ListViewItemSorter = new CustomSortAsc(); 
}; 

請參閱this recipe on sorting

比在每個比較中完成所有這些工作更好,緩存每個模型對象的排序值。如果值是「{整個九碼」,存儲「整個九碼」,並對這些值做一個簡單(快速)的字符串比較。

ObjectListView確實有它的own forum

2

儘管它與您的問題沒有直接關係,但我可能會建議一些代碼改進?顯然你原來的x和y對象是空格分隔的單詞。不知道是否有意不讓你將它們與空間重新結合,但我保持這種狀態。

public static class Extensions 
{ 
    public static IEnumerable<T> SkipIf<T>(this IEnumerable<T> items, Predicate<T> pred) 
     { 
      return pred(items.First()) ? items.Skip(1) : items; 
     } 
} 

public class CustomSortAsc : IComparer 
{ 
    int IComparer.Compare(Object x, Object y) 
    { 
     var ignorePredicates = new List<string> { "a", "the" }; 
     var px = Convert 
        .ToString(x) 
        .Replace("{", "") 
        .Replace("}", "") 
        .Split(' ') 
        .SkipIf(s => ignorePredicates.Contains(s.ToLower())) 
        .ToArray(); 

     var py = Convert 
        .ToString(y) 
        .Replace("{", "") 
        .Replace("}", "") 
        .Split(' ') 
        .SkipIf(s => ignorePredicates.Contains(s.ToLower())) 
        .ToArray(); 

     var newX = string.Join("", px); 
     var newY = string.Join("", py); 

     return string.Compare(newX, newY, true); 
    } 
} 

你可以只使用SkipWhile<>但會跳過多個「一」和「」開頭。可能沒問題 - 那麼你不需要SkipIf<>擴展。