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