Click here to Skip to main content
Click here to Skip to main content

Tagged as

Multi Column Sorting in DataGridView

, 14 May 2011
Rate this:
Please Sign up or sign in to vote.
Multi Column Sorting in DataGridView

Image1.jpg

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.

Image2.jpg

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;

            //Sort Images Together if images are in datagrid view
            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);

            //When Cell value is null or empty
            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;

            //compare Numeric values
            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;
            }
            //compare date values
            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 //compare string values
            {
                CompareResult = System.String.Compare(cellValue1, cellValue2);
            }

            CompareResult = CompareResult * sortOrderModifier;

            //if same values, perform this routine again
            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();

            //Populate the datagridview with users data
            PopulateDataGridView();
        }

        private void btnSort_Click(object sender, EventArgs e)
        {
            //get a List of all columns in the datagridview
            List<DataGridViewColumn> dgvColumns = new List<DataGridViewColumn>();
            foreach (DataGridViewColumn dgvCol in dataGridView1.Columns)
                dgvColumns.Add(dgvCol);

            //Pass the Column list to the sort Form
            using (SortColumnsForm form = new SortColumnsForm(this,dgvColumns))
            {
                if (form.ShowDialog() == DialogResult.OK)
                {
                    GridRowComparer rowComparer = 
				new GridRowComparer(form.SortOrderList);
                    dataGridView1.Sort(rowComparer);
                }
            }
        }

        /// <summary>
        /// Perform Sort fot the provided sort order list
        /// </summary>
        /// <param name="sortOrderList"></param>
        internal void PerformSort
	(List<KeyValuePair<DataGridViewColumn, bool>> sortOrderList)
        {
            GridRowComparer rowComparer = new GridRowComparer(sortOrderList);
            dataGridView1.Sort(rowComparer);
        }

        /// <summary>
        /// Populate the data
        /// </summary>
        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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Balu Sathish
Software Developer Calpine Technologies
India India
No Biography provided

Comments and Discussions

 
QuestionGREEEEEEEEEEEEEEEEEEEEEEEEEEEAT Solution Pinmemberantleite200113-Aug-13 0:30 
GeneralMy vote of 5 Pinmemberremi2226-Jun-12 11:12 
GeneralDataSource [modified] Pinmemberalegn16-May-11 22:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 14 May 2011
Article Copyright 2011 by Balu Sathish
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid