1

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

例如:

我有我的主要 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 的事件订阅?

谢谢您的帮助

4

2 回答 2

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;
于 2010-02-06T19:05:24.923 回答
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));
        }
    }
}
于 2010-02-06T10:25:21.460 回答