C# 如何通过单击列标题以编程方式对 DataGridView 进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/17113897/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Programmatically Sort a DataGridView by Clicking Column Header
提问by Marwan ?????
I have a Windows Form DataGridView that I need to apply custom sorting when a particular column header is clicked, and to reverse the sorting when the column header is clicked again.
我有一个 Windows 窗体 DataGridView,我需要在单击特定列标题时应用自定义排序,并在再次单击列标题时反转排序。
I will implement my own sorting algorithm, but I am unclear on how to wire or trigger the column header click with an event, and then keeping track of what was the last sort applied to that column so that I can reverse the sort process.
我将实现我自己的排序算法,但我不清楚如何通过事件连接或触发列标题单击,然后跟踪应用于该列的最后排序是什么,以便我可以反转排序过程。
The data for the DataGridView is being provided through a list, and the rows are being added as myList.Rows.Add(string_1, string_2, string_3)to the DataGridView.
DataGridView 的数据是通过列表提供的,并且正在向myList.Rows.Add(string_1, string_2, string_3)DataGridView添加行。
Please note that this is not my code, I have just been asked to implement a custom sort for each column.
请注意,这不是我的代码,我刚刚被要求为每一列实现自定义排序。
I have looked online, and have been unsuccessful in finding examples or explanation.
我在网上查过,一直没有找到例子或解释。
Can anyone provide me with sample code, or point me to a good site that shows a clear example of how to implement this.
任何人都可以向我提供示例代码,或者将我指向一个很好的站点,该站点显示了如何实现这一点的清晰示例。
Thanks in advance,
提前致谢,
Marwan
马万
采纳答案by King King
This is a solution which works, I bet there are more solutions to find out and hope others will jump in and give you them. You simply add custom code to the SortCompareevent handler for your DataGridViewand perform your own Compare function there, this compare function has 2 params and returns -1, 0 or 1:
这是一个有效的解决方案,我敢打赌有更多的解决方案可以找到,并希望其他人会加入并给你。您只需将自定义代码添加到您的SortCompare事件处理程序DataGridView并在那里执行您自己的比较函数,此比较函数有 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());
}
To test it, you simply add 3 rows to a one-column DataGridView such as a,b,c. Normally the ascending order (indicated by the up triangle on the ColumnHeader) is a,b,cbut with the Comparefunction above, it will be c,b,aand similarly, the descending order (indicated by the down triangle on the ColumnHeader) is c,b,abut with the Comparefunction above, it will be a,b,c.
要测试它,您只需将 3 行添加到一列 DataGridView,例如a,b,c. 通常升序(由 ColumnHeader 上的向上三角形表示)是,a,b,c但是对于Compare上面的函数,它将是c,b,a,类似地,降序(由 ColumnHeader 上的向下三角形表示)c,b,a但是对于Compare上面的函数,它将是a,b,c.
You can add more your own Compare functions and use each one for each Column you like. I think the important thing is how to define these functions, I don't have a clue on why you want to do so because the default comparison is OK.
您可以添加更多自己的比较函数,并为您喜欢的每一列使用每个函数。我认为重要的是如何定义这些函数,我不知道您为什么要这样做,因为默认比较是可以的。
回答by Aybe
Providing that you use the sorting method in this thread :
假设您在此线程中使用排序方法:
how to sort a datagridview by 2 columns
Here's a simple way to track the latest N columns the user has clicked in correct order.
这是跟踪用户按正确顺序单击的最新 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);
        }
    }
}

