开发者

Can I cast a LINQ query result to BindingList<T>?

开发者 https://www.devze.com 2022-12-19 02:54 出处:网络
From what I\'ve learned, you can\'t cast to BindingList, but rather you can wrap your result from the Linq query with a NEW BindingList. However, this doesn\'t work for me, because my Original Binding

From what I've learned, you can't cast to BindingList, but rather you can wrap your result from the Linq query with a NEW BindingList. However, this doesn't work for me, because my Original Binding list has some events attached to it and 开发者_运维技巧i would like to maintain the same events in my LINQ result set.

For example:

I have my main BindingList collection called "Reports" (of type IReport). This collection is being registered to an event as following: Reports.AddingNew += OnAddNewXReport;

now, when i would like to filter this big collection and extract only few matched items, i'm using Linq to get this matching list. To make this list a BindingList, i new to do the following:

var rs = Reports.Where(r => r.ReportType == ReportType.MyType).Select(o => (MyType) o);

return new BindingList<MyType>(rs.ToList());

As you can see, this newly created collection, will not fire when new item is being added.

Does anyone has any idea how to resolve this? is there anyway to close the event subscription from the original BindingList to the "filtered" BindingList?

Thanks for the help


I dont think there is an easy way to do this. I would make a derived BindingList<T> that chains and exposes the events you're interested in.

sealed class MyBindingList<T> : BindingList<T>
{
    public event EventHandler MyAddingNew;

    public MyBindingList(IList<T> collection)
        : base(collection)
    {
        //hook so that when BindingList.AddingNew is fired
        //it is chained to our new event
        base.AddingNew += MyBindingList_AddingNew;
    }

    public void MyBindingList_AddingNew(object sender, AddingNewEventArgs e)
    {
        if (MyAddingNew != null)
            MyAddingNew(sender, e);
    }

    public void RegisterEvents(MyBindingList<T> src)
    {
        //this is where you assign src events to your new list
        this.MyAddingNew = src.MyAddingNew;
    }
} 

Reason why you would need a derived type is that you cannot assign EventHandlers using just = (this.AddingNew = src.AddingNew) unless you're in the scope that defines it. When translated into your code you would have :

MyBindingList<MyType> Reports;
Reports.MyAddingNew += OnAddNewXReport;
var rs = Reports.Where(r => r.ReportType == ReportType.MyType)
                .Select(o => (MyType) o);    

MyBindingList<MyType> FilteredReports = new MyBindingList<MyType>(rs.ToList());
FilteredReports.RegisterEvents(Reports);
return FilteredReports;


I think one of the simplest way to achieve this is something like this:

var rs = Reports.Where(r => r.ReportType == ReportType.MyType).Select(o => (MyType) o);

var bs = new BindingList<MyType>();
foreach(var r in rs)
  bs.Add(r);

Another way is to create descendant for BindingList and in constructor fires OnListChanged for every item in new list:

sealed class MyBindingList<T> : BindingList<T>
{
    public MyBindingList(IList<T> collection)
        : base(collection)
    {
        for(int i = 0; i < collection.Count; ++i)
        {
            OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, idx));
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消