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

标签 c# sorting datagridview icomparer

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

上下文:我有一个 DataGridView(未绑定(bind)),其中有许多行。由于我想按多个列进行排序,因此我创建了一个实现 IComparer 的类,以便对网格行进行排序。我已经完成了对单个列进行排序的工作,但是我不确定现在如何更改此类以允许对多列> 1 进行排序。

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

示例:

  1. 用户点击第 4 列;数据按记录顺序排序 第 4 栏;
  2. 然后用户点击第 6 列;数据按以下顺序排序 第 4 列中的记录然后是第 6 列;
  3. 用户点击第 2 列;数据是 按第 4 列中的记录顺序排序,然后是第 6 列,然后是第 2 列;

等等

我目前拥有的内容如下:

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 循环的运行方式,它会正确地按升序/降序排序,但它仅按列表中的最终排序进行排序。

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

最佳答案

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

编辑

我不知何故忽略了它是未绑定(bind)的。如果你想这样做,你可以这样做:

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,但我想您已经知道了。

关于C# 使用 IComparer 对 x 列进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35214250/

相关文章:

c# - 从一页滑动到另一页

Java,找到两个数组的交集

c# - 你如何在 LINQ TO SQL 中按多列分组?

java - 使用多个字段对 solr 搜索结果进行排序 (solrj)

c - 按坐标到原点的距离对坐标数组进行排序

C# Winforms - 未绑定(bind) DataGridView 的辅助排序

c# - 将 ü 转换为 ü

Mysql VB.NET : Hiding column from datagridview null exception error (column is not null)

c# - mysql 向表列中插入查询

c# - .NET HttpClient - 现有连接被远程主机强行关闭