1

私が学んだことから、BindingList にキャストすることはできませんが、Linq クエリからの結果を NEW BindingList でラップすることができます。ただし、元のバインド リストにいくつかのイベントが関連付けられており、LINQ 結果セットで同じイベントを維持したいため、これはうまくいきません。

例えば:

「Reports」(IReport 型) というメインの BindingList コレクションがあります。このコレクションは次のようにイベントに登録されています: 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

これを達成する最も簡単な方法の1つは、次のようなものだと思います。

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

もう 1 つの方法は、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 に答える