【问题标题】:ObjectListView: Custom SorterObjectListView:自定义排序器
【发布时间】:2009-10-23 20:25:50
【问题描述】:

在控件 ObjectListView(http://objectlistview.sourceforge.net/html/cookbook.htm) 中,我正在尝试添加一个自定义排序器,它忽略“The”和“A”前缀。

我设法使用常规的 ListView 来做到这一点,但现在我切换到 ObjectListView(更多的功能,而且更方便),我似乎无法做到这一点。

以下是我认为的 ObjectListView 代码中的主要比较器...

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

升序的原始排序器,例如(忽略“A”和“The”)

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

【问题讨论】:

  • 你能补充更多信息吗,比如你得到什么样的结果,你如何将 CustomSortAsc 与列表视图挂钩等等?

标签: c# listview


【解决方案1】:

虽然它与您的问题没有直接关系,但我可以建议一些代码改进吗?显然,您原来的 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&lt;&gt;,但这会在开头跳过多个“a”和“the”。可能没问题 - 那么您不需要 SkipIf&lt;&gt; 扩展名。

【讨论】:

    【解决方案2】:

    安装一个 CustomSorter 委托,并在该委托中,将 ListItemSorter 放到 ObjectListView

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

    this recipe on sorting

    比每次比较都做所有这些工作更好,缓存每个模型对象的排序值。如果值为“{The} Whole Nine Yards”,则存储“整个九码”并对这些值进行简单(快速)的字符串比较。

    ObjectListView 确实有它的own forum

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-28
      • 1970-01-01
      相关资源
      最近更新 更多