我可以将LINQ查询结果转换为BindingList <t>?</t>

时间:2010-02-05 22:50:13

标签: c# linq bindinglist

根据我所学到的,你不能转换为BindingList,而是可以使用NEW BindingList包装Linq查询的结果。但是,这对我不起作用,因为我的原始绑定列表附加了一些事件,我想在我的LINQ结果集中保持相同的事件。

例如:

我有一个名为“Reports”的主要BindingList集合(类型为IReport)。此集合正在注册到以下事件: Reports.AddingNew + = OnAddNewXReport;

现在,当我想过滤这个大集合并只提取几个匹配的项目时,我正在使用Linq获取此匹配列表。为了使这个列表成为一个BindingList,我新增了以下内容:

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

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

如您所见,这个新创建的集合在添加新项目时不会触发。

有谁知道如何解决这个问题?无论如何关闭事件订阅从原始BindingList到“过滤”BindingList?

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

我认为有一种简单的方法可以做到这一点。我会创建一个派生的BindingList<T>链接并公开你感兴趣的事件。

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;
    }
} 

您需要派生类型的原因是您不能仅使用EventHandlers=)分配this.AddingNew = src.AddingNew,除非您在定义它的范围内。当翻译成您的代码时,您将拥有:

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;

答案 1 :(得分:0)

我认为实现这一目标的最简单方法之一就是:

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);

另一种方法是为BindingList创建后代,并在构造函数中为新列表中的每个项触发OnListChanged:

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));
        }
    }
}