In the past, tables were not always used to directly bind DataGridView, and there was no problem of not being able to sort. When I first tried List, I found that the sorting function could not be implemented no matter what. A friend said
Each column of the DataGridView has a Sortable. The default is Automatic. I changed it to NotSortable. No matter what the result is, it still doesn't work.
Some friends said that you can drag a bindingsource control. bindingsource.datasource=generic collection datagridview.datasource=bindingsource;
I found that it doesn't work either, so what should I do? Find out after checking the information
Using generics will lose the characteristics of DateTable. You must implement System.Collections.Generic.IComparer<T> to achieve sorting.
There is no other way but to realize it
Take a look at the code below, it basically looks like this
code
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Reflection;
namespace BaseFunction
{
class ObjectPropertyCompare<T> : System.Collections.Generic.IComparer<T>
{
private PropertyDescriptor property;
private ListSortDirection direction;
public ObjectPropertyCompare(PropertyDescriptor property, ListSortDirection direction)
{
this.property = property;
this.direction = direction;
}
#region IComparer<T>
/// <summary>
/// Comparison method
/// </summary>
/// <param name="x">Relative attribute x</param>
/// <param name="y">Relative attribute y</param>
/// <returns></returns>
public int Compare(T x, T y)
{
object xValue = x.GetType().GetProperty(property.Name).GetValue(x, null);
object yValue = y.GetType().GetProperty(property.Name).GetValue(y, null);
int returnValue;
if (xValue is IComparable)
{
returnValue = ((IComparable)xValue).CompareTo(yValue);
}
else if (xValue.Equals(yValue))
{
returnValue = 0;
}
else
{
returnValue = xValue.ToString().CompareTo(yValue.ToString());
}
if (direction == ListSortDirection.Ascending)
{
return returnValue;
}
else
{
return returnValue * -1;
}
}
public bool Equals(T xWord, T yWord)
{
return xWord.Equals(yWord);
}
public int GetHashCode(T obj)
{
return obj.GetHashCode();
}
#endregion
}
}
After implementing this interface, there is no rush. We have to write a SortableBindingList <T> :BindingList <T> class to bind data.
Basic implementation
code
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace BaseFunction
{
public class BindingCollection<T> : BindingList<T>
{
private bool isSorted;
private PropertyDescriptor sortProperty;
private ListSortDirection sortDirection;
protected override bool IsSortedCore
{
get { return isSorted; }
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override ListSortDirection SortDirectionCore
{
get { return sortDirection; }
}
protected override PropertyDescriptor SortPropertyCore
{
get { return sortProperty; }
}
protected override bool SupportsSearchingCore
{
get { return true; }
}
protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
{
List<T> items = this.Items as List<T>;
if (items != null)
{
ObjectPropertyCompare<T> pc = new ObjectPropertyCompare<T>(property, direction);
items.Sort(pc);
isSorted = true;
}
else
{
isSorted = false;
}
sortProperty = property;
sortDirection = direction;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
protected override void RemoveSortCore()
{
isSorted = false;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
//Sort
public void Sort(PropertyDescriptor property, ListSortDirection direction)
{
this.ApplySortCore(property, direction);
}
}
}
Now it’s time to figure out how to use it. It’s actually very simple.
direct
BindingCollection<object> objList = new BindingCollection<object>();
objList =your result set;
this.dataGridView1.DataSource = objList;
But now the problem is that I used List before and I don’t want to change it. Moreover, the Dll is called and what is returned is a List. I have no way to change it to BindingCollection<object>.
After thinking about it for a long time, I finally figured it out, but I don’t know how it is in terms of performance and other aspects, so I’ll post the code and let’s discuss it.
This is how I achieved it
code
//Classes that can implement sorting
BindingCollection<historyorderInfo> objList = new BindingCollection<historyorderInfo>();
//Load data
foreach (historyorderInfo item in tmpList)
{
objList.Add(item);
}
dgvhistory.DataSource = objList;
The tmpList here is the original List of the system I used before. I used foreach to import the original data into the BindingCollection.
This determination can achieve the effect I want. I don't know what's wrong with this. I hope I can get some advice from an expert, haha