Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用IComparer对x个列进行排序_C#_Sorting_Datagridview_Icomparer - Fatal编程技术网

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

C#使用IComparer对x个列进行排序,c#,sorting,datagridview,icomparer,C#,Sorting,Datagridview,Icomparer,我希望能够按x列对数据进行排序,其中x不是常数 上下文:我有一个DataGridView(未绑定),其中有许多行。由于我想按多个列进行排序,因此我创建了一个类,该类实现了IComparer,用于对网格行进行排序。我已经为一个单独的列进行了排序,但是我不确定现在如何修改这个类以允许对多个大于1的列进行排序 我以前看到的许多答案都提供了对两列或三列进行排序的示例,但这些示例似乎是比较A->B,然后是B->C等等。我在寻找更具活力的东西 例如: 用户点击第4栏;数据按中的记录顺序排序 第4栏 然后用户

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

上下文:我有一个DataGridView(未绑定),其中有许多行。由于我想按多个列进行排序,因此我创建了一个类,该类实现了IComparer,用于对网格行进行排序。我已经为一个单独的列进行了排序,但是我不确定现在如何修改这个类以允许对多个大于1的列进行排序

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

例如:

  • 用户点击第4栏;数据按中的记录顺序排序 第4栏
  • 然后用户单击第6列;数据按顺序排序 第4列记录,然后第6列记录
  • 用户点击第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));
            }
        }
    }
    
    公共类FormGrid:DataGridView
    {
    List ColIndexSorts=新列表();
    私有类GridSortData
    {
    公共int ColumnSortIndex;
    public System.Windows.Forms.SortOrder SortOrder;
    }       
    私有类GridSort:System.Collections.IComparer
    {
    私有静态int排序器=1;
    私有int排序列;
    公共网格排序(System.Windows.Forms.SortOrder SortOrder,int ColumnToSort)
    {
    排序列=列排序;
    SortOrder=SortOrder==System.Windows.Forms.SortOrder.Ascending?1:-1;
    }
    公共整数比较(对象x、对象y)
    {
    FormGridRow FirstCompariable=(FormGridRow)x;
    FormGridRow SecondComparable=(FormGridRow)y;
    int结果=1;
    结果=FirstComparable.Cells[SortingColumn].Value.ToString().CompareTo(SecondComparable.Cells[SortingColumn].Value.ToString());
    返回结果*排序器;
    }
    }
    私有void TSortGrid(int-ColIndexToSort,MouseButtons-MouseButton)
    {
    GridSortData ColumntSort=新的GridSortData();
    ColumnToSort.ColumnSortIndex=ColIndexToSort;
    if(MouseButton==System.Windows.Forms.MouseButtons.Left)
    {
    ColumnToSort.SortOrder=System.Windows.Forms.SortOrder.升序;
    }
    其他的
    {
    ColumnToSort.SortOrder=System.Windows.Forms.SortOrder.Descending;
    }
    添加(ColumnToSort);
    for(int i=0;i
    这个结果目前的问题是,在您选择了五列之后,colindexorts列表包含用于对五列进行排序的数据;但是,由于
    for
    循环的运行方式,它正确地按升序/降序排序,但它仅按列表中的最终排序


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

    您需要排序保持稳定。如果您使用的不是,请使用另一个,例如,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;
        }
    }
    
    私有类GridSort:System.Collections.IComparer
    {
    List ColIndexSorts=新列表();
    公共网格排序(列表colindexorts)
    {
    this.colindexorts=colindexorts;
    }
    公共整数比较(对象x、对象y)
    {
    FormGridRow FirstCompariable=(FormGridRow)x;
    FormGridRow SecondComparable=(FormGridRow)y;
    对于(int i=0;i

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

    我之前研究过DataGridView之外的排序,因为这确实可以提高排序时“按原样”处理值的效率,但主要问题是控件未绑定。因此,在排序时,它必须对控件外的数据进行排序,然后清除控件中的所有行并再次添加数据;对于几百张以上的唱片来说,它在用户界面上看起来很糟糕。非常感谢。老实说,我从未想过在sort函数本身中有“for”循环;如果现在将它放在它的外部,只会导致网格只保留它排序的最后一列!同样是的,您是正确的,所有进入网格的列在声明时都设置为编程排序,并且所有内容都在ColumnHeaderMouseClick事件中。我对其进行了精细处理,以便在按住“Shift”键时按多列排序,然后在松开并单击时返回到单列排序:-)