在尝试从ObservableCollection或BindingList进行子类化时,为什么会出现NullReferenceException?

时间:2011-08-08 16:58:29

标签: .net wpf ironpython observablecollection bindinglist

我正在使用ObservableCollection作为我的一些绑定的ItemsSource,并且遇到了我想手动调用OnCollectionChanged以通知应该重新检查列表的情况通过绑定引擎。 (BindingList类似物为OnListChanged)。

这就是麻烦开始的地方。实际上,这些方法是protected,如果不对这些类型进行子类化,则无法调用它们。 Ironpython supports this,但是当我尝试子类化时,即使我没有指定任何重写方法,它也会失败:

>>> class ObservableCollectionEx(System.Collections.ObjectModel.ObservableCollection):
...     pass
... 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
SystemError: Object reference not set to an instance of an object.

>>> class BindingListEx(System.ComponentModel.BindingList):
...     pass
... 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
SystemError: Object reference not set to an instance of an object.

我即将放弃,而我想做的就是打电话给OnCollectionChanged!救命啊!

2 个答案:

答案 0 :(得分:1)

ObservableCollection<T>BindingList<T>进行子类化是受支持的操作。这是我为BindingList<T>编写的一个示例,它公开OnListChanged并且不会抛出任何异常

class BindingListEx<T> : BindingList<T>
{
    public void ForceListChanged()
    {
        base.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, 0));
    }
}


class Program
{
    static void Main(string[] args)
    {
        var list = new BindingListEx<int>();
        list.Add(42);
        list.ForceListChanged();
    }
}

答案 1 :(得分:0)

在做了一些研究之后,我找到了一个解决方法。阅读this article on inheriting from generic classes揭示了幕后发生的事情,最明显的是这个解释:

  

Closed Construct generic是一个术语,用于表示子类是非泛型的,并且基类被参数化为具体类型。

public class SubClass : BaseClass<int>   {...}
  

Open Construct generic是用于引用基类和子类都被参数化为泛型类型的场景的术语。

public class SubClass<T> : BaseClass<T> {...}

根据这一点,我在原帖(继承自ObservableCollectionsBindingLists)中尝试做的是第二种形式;试图保持基类和子类参数化。虽然我仍然认为 在IronPython中有某种可能性,我无法弄清楚这样做的语法,所以我会选择第一种形式目前。而whaddaya知道,它有效:

>>> class BindingListEx(System.ComponentModel.BindingList[str]):
...     pass
... 
>>> 
>>> b = BindingListEx()
>>> b
<BindingListEx object at 0x000000000000002C>
>>> b.Add(3)
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: expected str, got int
>>> b.Add("cow")
>>> 

因此,在此示例中,BindingListEx是非泛型的,并且来自BindingList参数化基类的子类已被提供str作为其参数。这适用于现在。如果有人想出如何进行Open Construct泛型继承(那里的第二种形式),请随意在这里发布,你会得到接受的答案,因为那是我最初的目标。现在,这将是必须的。