Image 1
Image 1 is the parent form, which has a datagridview
control and a sort button, the sort button will pop up a ‘SortOrderForm
’ which allows to input the required sort order as in Image 2. The sort button in image 2 performs the sort function in the parent form.
Image 2
To implement this functionality, create a class file ‘GridRowComparer
’ as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DataGridViewMultiSort
{
public class GridRowComparer : System.Collections.IComparer
{
private List<KeyValuePair<DataGridViewColumn, bool>> _columnList;
public GridRowComparer(List<KeyValuePair<DataGridViewColumn, bool>> columnList)
{
_columnList = columnList;
}
public int Compare(object x, object y)
{
DataGridViewRow DataGridViewRow1 = ((DataGridViewRow)(x));
DataGridViewRow DataGridViewRow2 = ((DataGridViewRow)(y));
int CompareResult = compareResult(DataGridViewRow1, DataGridViewRow2, 0);
return (CompareResult);
}
public int compareResult(DataGridViewRow DataGridViewRow1,
DataGridViewRow DataGridViewRow2, int i)
{
DataGridViewColumn dgvColumn = _columnList[i].Key;
int sortOrderModifier = 0;
if (_columnList[i].Value)
sortOrderModifier = 1;
else
sortOrderModifier = -1;
int CompareResult = 0;
object value1 = DataGridViewRow1.Cells[dgvColumn.Index].Value;
object value2 = DataGridViewRow2.Cells[dgvColumn.Index].Value;
if ((value1 is System.Drawing.Bitmap) && !(value2 is System.Drawing.Bitmap))
return -1 * sortOrderModifier;
else if (!(value1 is System.Drawing.Bitmap) &&
(value2 is System.Drawing.Bitmap))
return 1 * sortOrderModifier;
else if (value1 is System.Drawing.Bitmap && value2 is System.Drawing.Bitmap)
return 0;
string cellValue1 = Convert.ToString
(DataGridViewRow1.Cells[dgvColumn.Index].Value);
string cellValue2 = Convert.ToString
(DataGridViewRow2.Cells[dgvColumn.Index].Value);
if ((cellValue1 == null || cellValue1 == string.Empty) &&
(cellValue2 != null || cellValue2 != string.Empty))
return -1 * sortOrderModifier;
else if ((cellValue1 != null || cellValue1 != string.Empty) &&
(cellValue2 == null || cellValue2 == string.Empty))
return 1 * sortOrderModifier;
else if ((cellValue1 == null || cellValue1 == string.Empty) &&
(cellValue2 == null || cellValue2 != string.Empty))
return 0;
if (dgvColumn.ValueType == typeof(Double))
{
double numVal1 = Convert.ToDouble(cellValue1);
double numVal2 = Convert.ToDouble(cellValue2);
if (numVal1 > numVal2)
CompareResult = 1;
else if (numVal1 < numVal2)
CompareResult = -1;
else
CompareResult = 0;
}
else if (dgvColumn.ValueType == typeof(DateTime))
{
DateTime cellValueDt1;
DateTime cellValueDt2;
if ((DateTime.TryParse(cellValue1, out cellValueDt1)) &&
(DateTime.TryParse(cellValue2, out cellValueDt2)))
{
if (cellValueDt1 > cellValueDt2)
CompareResult = 1;
else if (cellValueDt1 < cellValueDt2)
CompareResult = -1;
else
CompareResult = 0;
}
}
else
{
CompareResult = System.String.Compare(cellValue1, cellValue2);
}
CompareResult = CompareResult * sortOrderModifier;
if (CompareResult == 0)
{
if (i != _columnList.Count - 1)
{
i++;
CompareResult = compareResult(DataGridViewRow1, DataGridViewRow2, i);
}
}
return CompareResult;
}
}
}
And the sort operation can be performed by passing the new sort order list as List<KeyValuePair<DataGridViewColumn, bool>>
to GridRowComparer(…)
, where bool
is to know IsAscending
or not.
internal void PerformSort(List<KeyValuePair<DataGridViewColumn, bool>> sortOrderList)
{
GridRowComparer rowComparer = new GridRowComparer(sortOrderList);
dataGridView1.Sort(rowComparer);
}
Parent Form code follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DataGridViewMultiSort
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PopulateDataGridView();
}
private void btnSort_Click(object sender, EventArgs e)
{
List<DataGridViewColumn> dgvColumns = new List<DataGridViewColumn>();
foreach (DataGridViewColumn dgvCol in dataGridView1.Columns)
dgvColumns.Add(dgvCol);
using (SortColumnsForm form = new SortColumnsForm(this,dgvColumns))
{
if (form.ShowDialog() == DialogResult.OK)
{
GridRowComparer rowComparer =
new GridRowComparer(form.SortOrderList);
dataGridView1.Sort(rowComparer);
}
}
}
internal void PerformSort
(List<KeyValuePair<DataGridViewColumn, bool>> sortOrderList)
{
GridRowComparer rowComparer = new GridRowComparer(sortOrderList);
dataGridView1.Sort(rowComparer);
}
public void PopulateDataGridView()
{
dataGridView1.ColumnCount = 6;
dataGridView1.Columns[0].Name = "C0";
dataGridView1.Columns[1].Name = "C1";
dataGridView1.Columns[2].Name = "C2";
dataGridView1.Columns[3].Name = "C3";
dataGridView1.Columns[4].Name = "C4";
dataGridView1.Columns[5].Name = "C5";
dataGridView1.Columns[0].HeaderText = "C0";
dataGridView1.Columns[1].HeaderText = "C1";
dataGridView1.Columns[2].HeaderText = "C2";
dataGridView1.Columns[3].HeaderText = "C3";
dataGridView1.Columns[4].HeaderText = "C4";
dataGridView1.Columns[5].HeaderText = "C5";
dataGridView1.Columns[0].Width = 40;
dataGridView1.Columns[1].Width = 40;
dataGridView1.Columns[2].Width = 40;
dataGridView1.Columns[3].Width = 40;
dataGridView1.Columns[4].Width = 40;
dataGridView1.Columns[5].Width = 40;
dataGridView1.Rows.Add(new string[] { "1", "1", "1", "2", "2", "1" });
dataGridView1.Rows.Add(new string[] { "1", "2", "1", "2", "2", "2" });
dataGridView1.Rows.Add(new string[] { "1", "2", "2", "1", "1", "1" });
dataGridView1.Rows.Add(new string[] { "1", "1", "2", "1", "1", "2" });
dataGridView1.Rows.Add(new string[] { "2", "1", "2", "1", "2", "1" });
dataGridView1.Rows.Add(new string[] { "2", "1", "2", "1", "2", "2" });
dataGridView1.Rows.Add(new string[] { "2", "2", "1", "2", "1", "1" });
dataGridView1.Rows.Add(new string[] { "3", "2", "1", "2", "1", "2" });
dataGridView1.Rows.Add(new string[] { "3", "1", "1", "2", "2", "1" });
dataGridView1.AutoResizeColumns();
}
}
}
Please refer to the source code if you require the code of SortOrderForm
.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.