5

オブジェクトのCollectionChangedイベントのハンドラーがありますが、 を使用してイベントの に含まれるアイテムを取得する方法がわかりません。ObservableCollection<T>NotifyCollectionChangedEventArgsIList

コレクションに追加された新しいアイテムはNewItems、オブジェクトのプロパティにありIListます。Intellisense ではアクセスできません.Item[Index](ドキュメントによればアクセスできるはずです)。また、NewItemsリストをローカル変数にキャストすることもできません (デバッグによると、NewItemsリストはSystem.Collections.ArrayList.ReadOnlyListMSDN でアクセス可能なクラスとして存在しないようです)。 .)

私は何を間違っていますか?

例:

private void ThisCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        Item I = e.NewItems._________;//<<<<<cannot access any property to get the item
        var j = e.NewItems;//System.Collections.ArrayList.ReadOnlyList, see if you can find in the MSDN docs.
        IList I1 = (IList) e.NewItems;//Cast fails.
        IList<Item> = (IList<Item>)e.NewItems.________;//<<<<<<<Can't make this cast without an IList.Item[Index] accessor.
        var i = j[0]; //null
        var ioption = j.Item[0]; //no such accessor
        string s = (string)i; //null
    }

この例は、可能な限り一般的なものを維持していますが、それでも失敗します。

4

1 に答える 1

4

最小限で、完全で、検証可能な優れたコード例がなければ、何をする必要があるかを正確に言うことは不可能です。しかし、それまでの間、投稿したコードから少なくともいくつかの誤解を解消してみましょう。

private void ThisCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    Item I = e.NewItems._________;//<<<<<cannot access any property to get the item
    var j = e.NewItems;//System.Collections.ArrayList.ReadOnlyList, see if you can find in the MSDN docs.
    IList I1 = (IList) e.NewItems;//Cast fails.
    IList<Item> = (IList<Item>)e.NewItems.________;//<<<<<<<Can't make this cast without an IList.Item[Index] accessor.
    var i = j[0]; //null
    var ioption = j.Item[0]; //no such accessor
    string s = (string)i; //null
}
  1. NotifyCollectionChangedEventArgs.NewItemsIList非ジェネリック インターフェイスである type のプロパティです。NewItemsプロパティに関連するこのインターフェイスの 2 つの重要な側面はCount、アイテムを取得できることと、リストにインデックスを作成できることです。リストにインデックスを付けると、object;が返されます。それを適切な型にキャストするのはあなた次第です。
  2. System.Collections.ArrayList.ReadOnlyListフレームワークのプライベート クラスです。直接使用することは意図されていません。プロパティが返すのは単に実装ですIListNewItemsこの実装の重要な点は、読み取り専用であることです。、、 などIListのメンバーはサポートされていません。あなたができることは、アイテムを取り出すことだけです。しかし、同じくらい重要なのは、コードに関する限り、重要な型は. private 型のメンバーに直接アクセスすることはできません。これらは、実装するパブリック インターフェイスを介してのみ使用できます。Add()Insert()Remove()IList
  3. 「キャストが失敗する」という意味について具体的ではありません。NewItemsプロパティはすでにタイプ であるため、それは信じがたいことですIList。to へのキャストIListは自明に成功します。
  4. ジェネリックにキャストできないの事実です。あなたが扱っている実装はプライベートクラスであり、ジェネリックインターフェイスを実装できない可能性があります。結局のところ、 はMicrosoft によって作成され、.NET フレームワークに組み込まれています。彼らはあなたのタイプについてどのように知っていますか?IListIList<Item>IListSystem.Collections.ArrayList.ReadOnlyListIList<Item>ReadOnlyListItem
  5. Itemオブジェクトのプロパティ インデクサーを明示的に使用することは意図されていません。これは隠しメンバーとして存在します。代わりに、組み込みの C# 構文を使用して、オブジェクト自体にインデックスを付ける必要があります。すなわちe.NewItems[0]またはj[0]
  6. null変数にa を割り当てたら、いくらiキャストしてもそのnull値が別のものに変わることはありません。ではなくstring、他のタイプではありません。

さまざまなことを試しましたが、そのほとんどは意味をなさないので、機能しないことは驚くことではありません。あなたが得た最も近いものはj[0]表現です。ただし、直接使用することはできますe.NewItems。コードは次のようになります。

private void ThisCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Assumes that the elements in your collection are in fact of type "Item"
    Item item = (Item)e.NewItems[0];

    // do something with "item"
}

ただし、最初にコレクションにどのような変更が加えられたかを確認する必要があることに注意してください。NewItems実際に新しいアイテムがない場合、リストは空である可能性があります。null新しく設定されたアイテムの値が実際に だった場合、リストの要素は である可能性がありますnull。null 以外の要素値を正常にキャストできるかどうかは、実際にここにあるものと、コレクションにその型の要素が実際に含まれているかどうかItemによって異なります。Item同様に、にキャストしようとしますstring。リストに type の要素が含まれていない場合、stringnull 以外の要素値を にキャストしても機能しstringません。

しかし、これらはすべて残りのコードに固有の問題です。あなたはそれを提供していないので、私ができる最善のことは、このイベントとそれをサポートするタイプがどのように機能するかを現在誤解していると思われるすべての方法を一般的な用語で説明しようとすることです.

于 2016-08-21T18:55:13.070 に答える