Reputation: 2231
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.
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.
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
Upvotes: 3
Views: 31756
Reputation: 63387
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 SortCompare
event handler for your DataGridView
and perform your own Compare function there, this compare function has 2 params and returns -1, 0 or 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,c
but with the Compare
function above, it will be c,b,a
and similarly, the descending order (indicated by the down triangle on the ColumnHeader) is c,b,a
but with the Compare
function above, it will be 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.
Upvotes: 6
Reputation: 16692
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.
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);
}
}
}
Upvotes: 2