Reputation: 4621
I have several thousands MyClass objects stored in BindingList<MyClass>
. I want to sort them by date property MyClass.dt
.
Class BindingList doesn't support sorting directly. How I can sort BindingList<T>
not making duplicate copies of all objects? I need to sort them as in ascending, as in descending order, please.
I don't need special class SortableBindingList
as described in BindingList.Sort() to behave like a List.Sort(). I am searching for short solution in one o two lines of code.
Upvotes: 9
Views: 31872
Reputation: 121
//Convert it to a data table, then the Automatic will work.
DataGridView.DataSource = ConvertToDataTable(MyList).DefaultView;
public DataTable ConvertToDataTable(IBindingList list)
{
DataTable dt = new DataTable();
if (list.Count > 0)
{
Type typ = list[0].GetType();
PropertyInfo[] arrProps = typ.GetProperties();
foreach (PropertyInfo pi in arrProps)
{
Type colType = pi.PropertyType;
if (colType.IsGenericType)
{
colType = colType.GetGenericArguments()[0];
}
dt.Columns.Add(pi.Name, colType);
}
foreach (object obj in list)
{
DataRow dr = dt.NewRow();
foreach (PropertyInfo pi in arrProps)
{
if (pi.GetValue(obj, null) == null)
dr[pi.Name] = DBNull.Value;
else
dr[pi.Name] = pi.GetValue(obj, null);
}
dt.Rows.Add(dr);
}
}
return dt;
}
Upvotes: -1
Reputation: 11801
A quick way to implement a Sort on a BindingList is to use the constructor that takes a backing IList< T > as its argument. You can use a List<T>
as the backing and gain its Sort
capabilities.
Per the documentation
Use this BindingList to create a BindingList that is backed by list, which ensures that changes to list are reflected in the BindingList.
If your MyClass was defined as:
internal class MyClass
{
public MyClass(string name, Int32 num)
{
this.Name = name;
this.Num = num;
}
public string Name {get; set;}
public Int32 Num {get; set;}
}
then you could do something like this to sort it on the Num
field.
private List<MyClass> backing;
private BindingList<MyClass> bl;
private void InitializeBindingList()
{
backing = new List<MyClass>();
bl = new BindingList<MyClass>(backing);
bl.Add(new MyClass("a", 32));
bl.Add(new MyClass("b", 23));
bl.Add(new MyClass("c", 11));
bl.Add(new MyClass("d", 34));
bl.Add(new MyClass("e", 53));
}
private void SortBindingList()
{
backing.Sort((MyClass X, MyClass Y) => X.Num.CompareTo(Y.Num));
// tell the bindinglist to raise a list change event so that
// bound controls reflect the new item order
bl.ResetBindings();
}
}
You need to call BindingList.ResetBindings method after sorting the backing list to notify any bound controls that the BindingList
has changed and to update the control.
Upvotes: 6
Reputation: 62213
Linq would work.
var sortedListInstance = new BindingList<MyClass>(unsortedListInstance.OrderBy(x => x.dt).ToList());
Keep in mind you get a shallow copy of the sorted list, not duplicate instances of MyClass
.
Do not forget to include the namespace at the top of the code file System.Linq
Upvotes: 13