繁体   English   中英

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

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

据我了解,您不能转换为BindingList,而是可以使用新的BindingList包装来自Linq查询的结果。 但是,这对我来说不起作用,因为我的原始绑定列表中附加了一些事件,并且我想在LINQ结果集中维护相同的事件。

例如:

我的主要BindingList集合名为“ Reports”(类型为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的事件订阅?

谢谢您的帮助

我认为没有简单的方法可以做到这一点。 我将创建一个派生的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;
    }
} 

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

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;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM