C# 如何通过单击列标题以编程方式对DataGridView排序

C# 如何通过单击列标题以编程方式对DataGridView排序,c#,winforms,sorting,datagridview,C#,Winforms,Sorting,Datagridview,我有一个Windows窗体DataGridView,我需要在单击特定列标题时应用自定义排序,并在再次单击列标题时反转排序 我将实现我自己的排序算法,但我不清楚如何使用事件连接或触发列标题单击,然后跟踪应用于该列的最后一次排序,以便我可以反转排序过程 DataGridView的数据是通过一个列表提供的,这些行被添加为myList.rows.Add(string_1、string_2、string_3)到DataGridView 请注意,这不是我的代码,我刚刚被要求为每个列实现自定义排序 我在网上查

我有一个Windows窗体DataGridView,我需要在单击特定列标题时应用自定义排序,并在再次单击列标题时反转排序

我将实现我自己的排序算法,但我不清楚如何使用事件连接或触发列标题单击,然后跟踪应用于该列的最后一次排序,以便我可以反转排序过程

DataGridView的数据是通过一个列表提供的,这些行被添加为
myList.rows.Add(string_1、string_2、string_3)
到DataGridView

请注意,这不是我的代码,我刚刚被要求为每个列实现自定义排序

我在网上查过,没有找到例子或解释

有谁能给我提供示例代码,或者给我指出一个好的站点,它清楚地展示了如何实现这一点

提前感谢,


Marwan

假设您在此线程中使用排序方法:

下面是一种跟踪用户按正确顺序单击的最新N列的简单方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private readonly Stack<int> _stack = new Stack<int>();

        public Form1()
        {
            InitializeComponent();
        }

        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            // Column history
            _stack.Push(e.ColumnIndex);

            // Number of columns to track
            int columns = 3;

            // Build sort string
            int[] array = _stack.Distinct().ToArray();
            var builder = new StringBuilder();
            for (int index = 0; index < array.Length; index++)
            {
                int i = array[index];
                if (index >= columns)
                {
                    break;
                }

                DataGridViewColumn gridViewColumn = dataGridView1.Columns[i];
                string sort = null;
                switch (gridViewColumn.HeaderCell.SortGlyphDirection)
                {
                    case SortOrder.None:
                    case SortOrder.Ascending:
                        sort = "ASC";
                        break;
                    case SortOrder.Descending:
                        sort = "DESC";
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
                builder.AppendFormat("{0} {1}, ", gridViewColumn.Name, sort);
            }
            string s = builder.ToString();
            s = s.Remove(s.Length - 2);
            Console.WriteLine(s);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间Windows窗体应用程序1
{
公共部分类Form1:Form
{
私有只读堆栈_Stack=new Stack();
公共表格1()
{
初始化组件();
}
私有void dataGridView1_ColumnHeaderMouseClick(对象发送者,DataGridViewCellMouseEventArgs e)
{
//列历史记录
_stack.Push(如ColumnIndex);
//要跟踪的列数
int列=3;
//生成排序字符串
int[]数组=_stack.Distinct().ToArray();
var builder=新的StringBuilder();
for(int index=0;index=列)
{
打破
}
DataGridViewColumn gridViewColumn=dataGridView1.Columns[i];
字符串排序=null;
开关(gridViewColumn.HeaderCell.SortGlyphDirection)
{
案例排序器。无:
案例排序器。升序:
sort=“ASC”;
打破
案例排序器。下降:
sort=“DESC”;
打破
违约:
抛出新ArgumentOutOfRangeException();
}
AppendFormat(“{0}{1},”,gridViewColumn.Name,sort);
}
字符串s=builder.ToString();
s=s.移除(s.长度-2);
控制台。写入线(s);
}
}
}

这是一个有效的解决方案,我敢打赌还有更多的解决方案需要找到,希望其他人也能参与进来并提供给你。您只需向
DataGridView
SortCompare
事件处理程序添加自定义代码,并在其中执行自己的比较函数,此比较函数有2个参数并返回-1、0或1:

private void dataGridView_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
{
   if(e.Column == [your desired column]){
     e.Handled = true;
     e.SortResult = Compare(e.CellValue1, e.CellValue2);
   }
}
//Here is my compare function, it simply reverts the normal comparison result
private int Compare(object o1, object o2)
{
   return -o1.ToString().CompareTo(o2.ToString());
}
要测试它,只需向一列DataGridView添加3行,例如
a、b、c
。通常,升序(由列标题上的上三角表示)为
a,b,c
,但使用上面的
Compare
功能,升序将为
c,b,a
,同样,降序(由列标题上的下三角表示)为
c,b,a
,但使用上面的
Compare
功能,它将是
a、b、c


您可以添加更多自己的比较函数,并为您喜欢的每一列使用每一个函数。我认为重要的是如何定义这些函数,我不知道您为什么要这样做,因为默认比较是可以的。

谁否决了OP请留下一些评论,以帮助他下次做得更好?我会看一下,并尽快与您联系。至于排序的原因,它是DataGridView中显示的数据所特有的。这不是我最初的想法,但它最终非常适合我的需要。非常感谢您花时间解释。这真的很有帮助。我很久没有看到如此优雅的解决方案了,如果可以的话,我会投+10票。非常感谢你!谢谢…我不确定这是否适用于我的情况,但我会很快研究它。