IComparer按不同的标准排序

时间:2012-07-12 17:38:28

标签: c# .net listview sorting icomparer

我有一个ListView,我试图对它们进行排序,其中首先是BackColor红色的项目,然后是ForeColor红色的项目,最后是剩下的项目这些项目,但所有项目都应按其组内的名称进行排序。

我写了这段代码,但我仍然得到了大量相同的项目:

public int Compare (object x, object y)
{
    int CompareResult;
    ListViewItem a = (ListViewItem) x;
    ListViewItem b = (ListViewItem) y;

    if (a.BackColor == Color.FromArgb (200, 0, 0))
    {
        if (b.BackColor == Color.FromArgb(200, 0, 0))
        {
            return a.Text.CompareTo(b.Text);
        }
        else
        {
            return -1;
        }
    }
    else
    {
        if (a.ForeColor == Color.FromArgb(200, 0, 0))
        {
            if (b.ForeColor == Color.FromArgb(200, 0, 0))
            {
                return a.Text.CompareTo(b.Text);
            }
            else
            {
                return -1;
            }
        }
        else
        {
            return 1;
        }
    }
}

5 个答案:

答案 0 :(得分:1)

问题在于你错过了几个案例:

  • 如果a为非红色,则每次都会返回1,而您确实想要查看b是否有红色前景或背景。如果是,则需要返回1.如果没有,则需要比较文本。
  • 如果a有红色前景,但b没有,则始终返回-1,而您首先需要检查b是否有红色背景。如果是,则需要返回1.

这是我能立即看到的两个,但为了正确解决这个问题,你需要确保每一对可能的输入(红色前置,红色后退和非红色两个输入)将导致正确的比较。

答案 1 :(得分:1)

你似乎错过了一些案例。我确保所有9个案件都得到处理。 (有些可能是多余的)

答案 2 :(得分:1)

重构一下:

没有运行,但似乎是正确的 -

public int Compare(object x, object y)
        {
            ListViewItem a = (ListViewItem)x;
            ListViewItem b = (ListViewItem)y;

            Color red = Color.FromArgb(200, 0, 0);

            int textCompare = a.Text.CompareTo(b.Text);
            bool bothRed = a.BackColor == red && b.BackColor == red;
            bool bothOtherColor = a.BackColor != red && b.BackColor != red;

            return bothRed || bothOtherColor ? textCompare : b.BackColor == red ? 1 : -1;
}

答案 3 :(得分:1)

如果您首先确定项目所在的“组”,则可以使这更简单,更容易阅读:

class Comparer : IComparer<ListViewItem> 
{       
    public int Compare (ListViewItem left, ListViewItem right)
    {
        var leftGroup = DetermineGroup(left);
        var rightGroup = DetermineGroup(right);

        if(leftGroup == rightGroup) 
        { 
           return left.Text.CompareTo(right.Text);
        }

        return leftGroup.CompareTo(rightGroup);
    }

    enum Grouping 
    {
        RedBack,
        RedFront,
        Neither
    }

    Grouping DetermineGroup(ListViewItem x) 
    {
        if(x.BackColor == Color.Red) return Grouping.RedBack;
        if(x.ForeColor == Color.Red) return Grouping.RedFront;

        return Grouping.Neither;
    }
}

答案 4 :(得分:0)

好的,这有效:

public int Compare ( object x, object y )
{
    int CompareResult;
    ListViewItem a = ( ListViewItem ) x;
    ListViewItem b = ( ListViewItem ) y;

    Color red = Color.FromArgb(200, 0, 0);

    if (a.BackColor == red)
    {
        if (b.BackColor == red)
        {
            return a.Text.CompareTo(b.Text);
        }
        else
        {
            return -1;
        }
    }
    else
    {
        if (b.BackColor == red)
        {
            return 1;
        }
        else
        {
            if (a.ForeColor == red)
            {
                if (b.ForeColor == red)
                {
                    return a.Text.CompareTo(b.Text);
                }
                else
                {
                    return -1;
                }
            }
            else
            {
                if (b.ForeColor == red)
                {
                    return 1;
                }
                else
                {
                    return a.Text.CompareTo(b.Text);
                }
            }
        }
    }
}