C#使用IComparer对x列进行排序

时间:2016-02-05 00:24:27

标签: c# sorting datagridview icomparer

我希望能够按x列对数据进行排序,其中x不是常量。

上下文:我有一个DataGridView(未绑定),其中有许多行。由于我想按多列排序,我创建了一个实现IComparer的类,用于排序网格行。我有这个工作来排序单个列但是我不确定如何改变这个类以允许排序多个列> 1。

我之前看到的许多答案提供了对两列或三列进行分类的示例,但是这些似乎是比较A-> B,然后是B-> C等等。我正在寻找一些更有活力的东西。

示例:

  1. 用户点击第4列;数据按记录顺序排序 第4栏;
  2. 用户然后点击第6列;数据按顺序排序 第4栏那么记录第6栏;
  3. 用户点击第2列;数据是 按照第4栏中的记录顺序排序,然后是第6栏,第2栏;
  4. 我目前的情况如下:

    public class FormGrid : DataGridView
    {
        List<GridSortData> ColIndexSorts = new List<GridSortData>();
    
        private class GridSortData
        {
            public int ColumnSortIndex;
            public System.Windows.Forms.SortOrder SortOrder;
        }       
    
        private class GridSort : System.Collections.IComparer
        {
            private static int SortOrder = 1;
            private int SortingColumn;
    
            public GridSort(System.Windows.Forms.SortOrder sortOrder, int ColumnToSort)
            {
                SortingColumn = ColumnToSort;
                SortOrder = sortOrder == System.Windows.Forms.SortOrder.Ascending ? 1 : -1;
            }
    
            public int Compare(object x, object y)
            {
                FormGridRow FirstComparable = (FormGridRow)x;
                FormGridRow SecondComparable = (FormGridRow)y;
    
                int result = 1;
    
                        result =  FirstComparable.Cells[SortingColumn].Value.ToString().CompareTo(SecondComparable.Cells[SortingColumn].Value.ToString());
    
                return result * SortOrder;
            }
        }
    
        private void TSortGrid(int ColIndexToSort, MouseButtons MouseButton)
        {
            GridSortData ColumnToSort = new GridSortData();
    
            ColumnToSort.ColumnSortIndex = ColIndexToSort;
    
            if (MouseButton == System.Windows.Forms.MouseButtons.Left)
            {
                ColumnToSort.SortOrder = System.Windows.Forms.SortOrder.Ascending;
            }
            else
            {
                ColumnToSort.SortOrder = System.Windows.Forms.SortOrder.Descending;
            }
    
            ColIndexSorts.Add(ColumnToSort);
    
            for (int i = 0; i < ColIndexSorts.Count; i++)
            {
                this.Sort(new GridSort(ColIndexSorts[i].SortOrder, ColIndexSorts[i].ColumnSortIndex));
            }
        }
    }
    

    此结果的当前问题是,在您选择了五列之后,ColIndexSorts列表包含用于排序五列的数据;但是,由于for循环的运行方式,它正在按正确的升序/降序进行排序,但它只按列表中的最终排序进行排序。

    我觉得解决这个问题的方法是对要执行的排序列表中的每种排序,记住每次排序后的行顺序,然后对该数据执行额外的排序。

1 个答案:

答案 0 :(得分:3)

您需要排序才能保持稳定。如果您使用的那个不是,请使用另一个,例如,linq在IEnumerable上提供一个。我承认这意味着对代码进行了很大的改动,因为您需要在datagridview之外进行排序并仅分配结果。通过字符串表示来比较值对数字来说远非完美。

修改

我莫名其妙地忽略了它没有束缚。如果你想这样,你可以这样做:

private class GridSort : System.Collections.IComparer
{
    List<GridSortData> ColIndexSorts = new List<GridSortData>();

    public GridSort(List<GridSortData> ColIndexSorts)
    {
        this.ColIndexSorts = ColIndexSorts;
    }

    public int Compare(object x, object y)
    {
        FormGridRow FirstComparable = (FormGridRow)x;
        FormGridRow SecondComparable = (FormGridRow)y;

        for (int i = 0; i < ColIndexSorts.Count; ++i)
        {
            int index = ColIndexSorts[i].ColumnSortIndex;
            object a = FirstComparable.Cells[index].Value;
            object b = SecondComparable.Cells[index].Value;
            int result = a.ToString().CompareTo(b.ToString());
            if (result != 0)
            {
                if (ColIndexSorts[i].SortOrder == SortOrder.Ascending)
                {
                    return result;
                }
                else
                {
                    return -result;
                }
            }
        }

        return 0;
    }
}

您必须将所有列的SortMode设置为编程并处理ColumnHeaderMouseClick,但我想您已经知道了。