Sort Datagridview Columns in C#? (Windows Form)

Sort dataGridView columns in C# ? (Windows Form)

There's a method on the DataGridView called "Sort":

this.dataGridView1.Sort(this.dataGridView1.Columns["Name"], ListSortDirection.Ascending);

This will programmatically sort your datagridview.

winform datagridview column sort

Both answers above are correct. I've also found another article that points to code that converts a list to a "SortableBindingList". Of course you can change the class name if you like. Look at the marked answer in

Sortable List

How to Programmatically Sort a DataGridView by Clicking Column Header

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.

How to sort a DataGridView based on its column content?

You need to create another column by which to sort (you can make it's Visible property = false). Paste all of this code into a new windows Form and it will work exactly as you described (delete the FormX.designer.cs file). The SortableCode column uses Regular Expressions to remove the leading alpha characters.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace StackOverflowQuestion21361045
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public class myClass
{
public string Code { get; set; }

public string SortableCode
{
get
{
return Regex.Replace(Code, @"^[^\d]+", string.Empty);
}
}
}

private readonly SortableBindingList<myClass> objList = new SortableBindingList<myClass>();

private void Form1_Load(object sender, EventArgs e)
{
objList.Add(new myClass {Code = "A23"});
objList.Add(new myClass {Code = "B12"});
objList.Add(new myClass {Code = "C04" });
dataGridView1.DataSource = objList;
dataGridView1.Sort(dataGridView1.Columns[1], ListSortDirection.Ascending);
}

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
DataGridViewColumn newColumn = dataGridView1.Columns[e.ColumnIndex];
DataGridViewColumn previouslySortedColumn = dataGridView1.SortedColumn;
ListSortDirection direction;

if (newColumn == dataGridView1.Columns[0])
newColumn = dataGridView1.Columns[1]; //if the user sorts by code, change the column so as to sort by SortableCode
// If oldColumn is null, then the DataGridView is not sorted.
if (previouslySortedColumn != null)
{
// Sort the same column again, reversing the SortOrder.
if (previouslySortedColumn == newColumn &&
dataGridView1.SortOrder == SortOrder.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
// Sort a new column and remove the old SortGlyph.
direction = ListSortDirection.Ascending;
previouslySortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
else
{
direction = ListSortDirection.Ascending;
}

// Sort the selected column.
dataGridView1.Sort(newColumn, direction);
newColumn.HeaderCell.SortGlyphDirection =
direction == ListSortDirection.Ascending ?
SortOrder.Ascending : SortOrder.Descending;
}

private void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
// Put each of the columns into programmatic sort mode.
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
column.SortMode = DataGridViewColumnSortMode.Programmatic;
}
}

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.Size = new System.Drawing.Size(284, 261);
this.dataGridView1.TabIndex = 0;
this.dataGridView1.ColumnHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView1_ColumnHeaderMouseClick);
this.dataGridView1.DataBindingComplete += new System.Windows.Forms.DataGridViewBindingCompleteEventHandler(this.dataGridView1_DataBindingComplete);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.dataGridView1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.DataGridView dataGridView1;

public class SortableBindingList<T> : BindingList<T>
{
private ArrayList sortedList;
private ArrayList unsortedItems;
private bool isSortedValue;

public SortableBindingList()
{
}

public SortableBindingList(IList<T> list)
{
foreach (object o in list)
{
this.Add((T)o);
}
}

protected override bool SupportsSearchingCore
{
get
{
return true;
}
}

protected override int FindCore(PropertyDescriptor prop, object key)
{
PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
T item;

if (key != null)
{
for (int i = 0; i < Count; ++i)
{
item = (T)Items[i];
if (propInfo.GetValue(item, null).Equals(key))
return i;
}
}
return -1;
}

public int Find(string property, object key)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
PropertyDescriptor prop = properties.Find(property, true);

if (prop == null)
return -1;
else
return FindCore(prop, key);
}

protected override bool SupportsSortingCore
{
get { return true; }
}

protected override bool IsSortedCore
{
get { return isSortedValue; }
}

ListSortDirection sortDirectionValue;
PropertyDescriptor sortPropertyValue;

protected override void ApplySortCore(PropertyDescriptor prop,
ListSortDirection direction)
{
sortedList = new ArrayList();

Type interfaceType = prop.PropertyType.GetInterface("IComparable");

if (interfaceType == null && prop.PropertyType.IsValueType)
{
Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);

if (underlyingType != null)
{
interfaceType = underlyingType.GetInterface("IComparable");
}
}

if (interfaceType != null)
{
sortPropertyValue = prop;
sortDirectionValue = direction;

IEnumerable<T> query = base.Items;
if (direction == ListSortDirection.Ascending)
{
query = query.OrderBy(i => prop.GetValue(i));
}
else
{
query = query.OrderByDescending(i => prop.GetValue(i));
}
int newIndex = 0;
foreach (object item in query)
{
this.Items[newIndex] = (T)item;
newIndex++;
}
isSortedValue = true;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));

}
else
{
throw new NotSupportedException("Cannot sort by " + prop.Name +
". This" + prop.PropertyType.ToString() +
" does not implement IComparable");
}
}

protected override void RemoveSortCore()
{
int position;
object temp;

if (unsortedItems != null)
{
for (int i = 0; i < unsortedItems.Count; )
{
position = this.Find("LastName",
unsortedItems[i].GetType().
GetProperty("LastName").GetValue(unsortedItems[i], null));
if (position > 0 && position != i)
{
temp = this[i];
this[i] = this[position];
this[position] = (T)temp;
i++;
}
else if (position == i)
i++;
else
unsortedItems.RemoveAt(i);
}
isSortedValue = false;
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
}

public void RemoveSort()
{
RemoveSortCore();
}
protected override PropertyDescriptor SortPropertyCore
{
get { return sortPropertyValue; }
}

protected override ListSortDirection SortDirectionCore
{
get { return sortDirectionValue; }
}

}
}
}

Can't sort C# DataGridView column as integers

You never show where you're creating the DataTable that you're binding to (dsComponentes.Tables["Queue"]), but when you add that column you should be able to indicate that it's an int.

var dataTable = new DataTable();
dataTable.Columns.Add("ColumnName", typeof(int));

This will cause the bound DataGridView to sort that column as integers.

It looks like there is a DataType in the Columns Collection Editor as well, if you're using the designer to create your DataSet. You can set the type to System.Int32 on that column and it will sort as you expect.

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

var frm = new Form()
{
Text = "Data Grid View Form",
Name = "DataGridViewForm",
Size = new System.Drawing.Size(400, 400)
};
var dataGridView1 = new DataGridView();

var dataTable = new DataTable();
dataGridView1.DataSource = dataTable;
dataGridView1.Dock = DockStyle.Fill;

dataTable.Columns.Add("Id", typeof(int));
dataTable.Columns.Add("IdAsString", typeof(string));
var r1 = dataTable.NewRow();
r1["Id"] = 1;
r1["IdAsString"] = "1";
dataTable.Rows.Add(r1);

var r2 = dataTable.NewRow();
r2["Id"] = 11;
r2["IdAsString"] = "11";
dataTable.Rows.Add(r2);

var r3 = dataTable.NewRow();
r3["Id"] = 2;
r3["IdAsString"] = "2";
dataTable.Rows.Add(r3);

var r4 = dataTable.NewRow();
r4["Id"] = 22;
r4["IdAsString"] = "22";
dataTable.Rows.Add(r4);

frm.Controls.Add(dataGridView1);

Application.Run(frm);
}
}
}

How to sort a Column in DataGridView that is bound to a List in WinForm?

you Can try this......

Complete code to sort the column of datagridview whose datasource is a generic List

//-----------------------------------------------------------------------------------------
//In the form - In constructor or form load, populate the grid.
//--------------------------------------------------------------------------------------------

    List<student> students;

private void PopulateList()
{
student std1 = new student("sss", 15, "Female");
student std2 = new student("ddd", 12, "Male");
student std3 = new student("zzz", 16, "Male");
student std4 = new student("qqq", 14, "Female");
student std5 = new student("aaa", 11, "Male");
student std6 = new student("lll", 13, "Female");

students = new List<student>();
students.Add(std1);
students.Add(std2);
students.Add(std3);
students.Add(std4);
students.Add(std5);
students.Add(std6);

dataGridView1.DataSource = students;
}

//---------------------------------------------------------------------------------------------

//Comparer class to perform sorting based on column name and sort order
//---------------------------------------------------------------------------------------------

class StudentComparer : IComparer<Student>
{
string memberName = string.Empty; // specifies the member name to be sorted
SortOrder sortOrder = SortOrder.None; // Specifies the SortOrder.

/// <summary>
/// constructor to set the sort column and sort order.
/// </summary>
/// <param name="strMemberName"></param>
/// <param name="sortingOrder"></param>
public StudentComparer(string strMemberName, SortOrder sortingOrder)
{
memberName = strMemberName;
sortOrder = sortingOrder;
}

/// <summary>
/// Compares two Students based on member name and sort order
/// and return the result.
/// </summary>
/// <param name="Student1"></param>
/// <param name="Student2"></param>
/// <returns></returns>
public int Compare(Student Student1, Student Student2)
{
int returnValue = 1;
switch (memberName)
{
case "Name" :
if (sortOrder == SortOrder.Ascending)
{
returnValue = Student1.Name.CompareTo(Student2.Name);
}
else
{
returnValue = Student2.Name.CompareTo(Student1.Name);
}

break;
case "Sex":
if (sortOrder == SortOrder.Ascending)
{
returnValue = Student1.Sex.CompareTo(Student2.Sex);
}
else
{
returnValue = Student2.Sex.CompareTo(Student1.Sex);
}
break;
default:
if (sortOrder == SortOrder.Ascending)
{
returnValue = Student1.Name.CompareTo(Student2.Name);
}
else
{
returnValue = Student2.Name.CompareTo(Student1.StudentId);
}
break;
}
return returnValue;
}
}

//---------------------------------------------------------------------------------------------

// Performing sort on click on Column Header
//---------------------------------------------------------------------------------------------

    private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
//get the current column details
string strColumnName = dataGridView1.Columns[e.ColumnIndex].Name;
SortOrder strSortOrder = getSortOrder(e.ColumnIndex);

students.Sort(new StudentComparer(strColumnName, strSortOrder));
dataGridView1.DataSource = null;
dataGridView1.DataSource = students;
customizeDataGridView();
dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
}

/// <summary>
/// Get the current sort order of the column and return it
/// set the new SortOrder to the columns.
/// </summary>
/// <param name="columnIndex"></param>
/// <returns>SortOrder of the current column</returns>
private SortOrder getSortOrder(int columnIndex)
{
if (dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.None ||
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.Descending)
{
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
return SortOrder.Ascending;
}
else
{
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
return SortOrder.Descending;
}
}

I am hoping that it will helps you.....

how to sort a datagridview by 2 columns

If your DataGridView is databound, you can sort your Datatable view and rebind to datatable as below:

private DataGridView dataGridView1 = new DataGridView();
private BindingSource bindingSource1 = new BindingSource();

private void Form1_Load(object sender, System.EventArgs e)
{
// Bind the DataGridView to the BindingSource
dataGridView1.DataSource = bindingSource1;
SortDataByMultiColumns(); //Sort the Data
}

private void SortDataByMultiColumns()
{
DataView view = dataTable1.DefaultView;
view.Sort = "day ASC, status DESC";
bindingSource1.DataSource = view; //rebind the data source
}

OR, without using bindingsource and binding directly to DataView:

private void SortDataByMultiColumns()
{
DataView view = ds.Tables[0].DefaultView;
view.Sort = "day ASC, status DESC";
dataGridView1.DataSource = view; //rebind the data source
}


Related Topics



Leave a reply



Submit