NotifyCollectionChangedEventArgs项无法访问

时间:2016-08-21 18:06:36

标签: c# inotifycollectionchanged

我有一个CollectionChanged对象ObservableCollection<T>事件的处理程序,无法弄清楚如何使用NotifyCollectionChangedEventArgs检索IList中包含的项目事件。

添加到集合中的新项目位于NewItems属性中,IList对象。 Intellisense不允许我访问.Item[Index](我应该能够根据文档),也不能将NewItems列表转换为局部变量(根据调试NewItems列表是System.Collections.ArrayList.ReadOnlyList,它似乎不是MSDN中的可访问类。)

我做错了什么?

示例:

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 个答案:

答案 0 :(得分:3)

如果没有好的Minimal, Complete, and Verifiable code example,就无法确切地说出你需要做什么。但与此同时,让我们尝试从您发布的代码中至少清除一些误解:

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.NewItems是一个属性,类型为IList,是非泛型接口。与NewItems属性相关的此接口的两个关键方面是,您可以获取Count项,并且可以索引列表。索引列表将返回object;你应该把它强制转换成合适的类型。
  2. System.Collections.ArrayList.ReadOnlyList是框架中的私有类。你不打算直接使用它。它只是IList属性返回的NewItems的实现。这个实现的重要一点是它是只读的。不支持IListAdd()Insert()Remove()个成员。你所能做的只是拿出物品。但同样重要的是,就您的代码而言,唯一重要的类型是IList。您无法直接访问私有类型的成员;它们只能通过它们实现的公共接口使用。
  3. 您并不具体说明“投放失败”的含义。这是不可信的,因为NewItems属性已经是IList类型。对IList的强制转换将会成功。
  4. 是,您无法将IList强制转换为通用IList<Item>。您正在处理的IList的实现是私有类System.Collections.ArrayList.ReadOnlyList,它不可能实现通用IList<Item>接口。毕竟,ReadOnlyList是由Microsoft编写的,位于.NET框架中。他们如何了解您的Item类型?
  5. 您并不打算明确使用对象的Item属性索引器。这作为隐藏成员存在。相反,您应该使用内置的C#语法来索引对象本身。即e.NewItems[0]j[0]
  6. null分配给变量i后,任何投射量都不会将null值更改为其他内容。不是string,不是其他类型。
  7. 你已经尝试了很多不同的东西,其中大多数没有任何意义,因此它们不起作用并不奇怪。你得到的最接近的是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。是否可以成功将非空元素值强制转换为Item取决于Item实际存在于何处,以及您的集合是否实际上具有该类型的元素。同样,您尝试投放到string。如果列表不包含string类型的元素,则将任何非null元素值强制转换为string将无效。

    但这些都是特定于其余代码的问题。你没有提供这个,所以我能做的最好的事情就是试着用一般的术语解释你目前误解这个事件及其支持类型的工作方式。