BindingList and LINQ?
Asked Answered
D

3

14

I am new with Linq and I would like to sort some data that are in the BindingList. Once I did my Linq query, I need to use back the BindingList collection to bind my data.

 var orderedList = //Here is linq query
 return (BindingList<MyObject>)orderedList;

This compiled but fails in execution, what is the trick?

Delitescence answered 25/11, 2008 at 19:52 Comment(0)
E
20
new BindingList<MyObject>(orderedList.ToList())
Eklund answered 25/11, 2008 at 19:54 Comment(1)
Won't this break anybody who's subscribed to events on the list?Nomo
I
5

You can't always cast any collection type into any other collection. In terms of when the the compiler checks casting, check out this post on Compile-time vs runtime casting

However, you can easily produce a BindingList from an enumerable by doing some of the plumbing yourself. Just add the following Extension Method onto any Enumerable type to convert the collection into a BindingList.

C#:

static class ExtensionMethods
{
    public static BindingList<T> ToBindingList<T>(this IEnumerable<T> range)
    {
        return new BindingList<T>(range.ToList());
    }
}

//use like this:
var newBindingList = (from i in new[]{1,2,3,4} select i).ToBindingList();

VB:

Module ExtensionMethods
    <Extension()> _
    Public Function ToBindingList(Of T)(ByVal range As IEnumerable(Of T)) As BindingList(Of T)
        Return New BindingList(Of T)(range.ToList())
    End Function
End Module

'use like this:
Dim newBindingList = (From i In {1, 2, 3, 4}).ToBindingList()
Illative answered 28/2, 2014 at 20:23 Comment(1)
When T implements INotifyPropertyChanged, you can about double your efficiency by iterating range and adding each item to the BindingList directly. As it is, range.ToList() will enumerate range to add each item to a List<T> and then BindingList<T> will enumerate that list (again) to hook up the PropertyChanged event handler to each item. Skipping .ToList could improve performance for a really large collection.Gertrudegertrudis
P
2

That above only works when your linq query's select projection is explicitly typed as MyObject rather than select new which creates an instance of an anonymous object. In such cases the typeof(orderedList.ToList()) winds up as something akin to this: System.Collections.Generic.List<<>f__AnonymousType1>

ie: this should work:

var result = (from x in MyObjects
              where (wherePredicate( x ))
              select new MyObject {
                  Prop1 = x.Prop1,
                  Prop2 = x.Prop2
              }).ToList();
return new BindingList<MyObject>( result );

this will not:

var result = from x in db.MyObjects
             where(Predicate(x))
             select new {
                Prop1 = x.Prop1
                Prop2 = x.Prop2
            };
return new BindingList<MyObject>(result.ToList())
//creates the error: CS0030 "Cannot convert type 'AnonymousType#1' to 'MyObject'

In the second case they typeof(result) is: System.Collections.Generic.List<<>f__AnonymousType2> (the type params match the properties set in your select projection)

reference: http://blogs.msdn.com/swiss_dpe_team/archive/2008/01/25/using-your-own-defined-type-in-a-linq-query-expression.aspx

Peake answered 11/2, 2009 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.