event不为null但_invocationList为null?

时间:2010-12-20 19:51:24

标签: c# .net winforms events

我想如果我有这段代码:

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null) PropertyChanged(this, e);
    }

并且PropertyChanged事件未被挂钩,ProeprtyChanged将是null,但我得到的PropertyChanged非空且其_invocationList } member是null,其_invocationCount成员为0.这(我认为)在调用PropertyChanged(this, e)时导致ArgumentOutOfRangeException。知道问题在哪里?

这是OnClick事件中的堆栈跟踪:

  

at System.Collections.ArrayList.get_Item(Int32 index)      在System.Windows.Forms.BindingsCollection.get_Item(Int32索引)      在System.Windows.Forms.BindingManagerBase.PushData(布尔和成功)      在System.Windows.Forms.PropertyManager.OnCurrentChanged(EventArgs ea)      在System.Windows.Forms.BindToObject.PropValueChanged(Object sender,EventArgs e)      在System.EventHandler.Invoke(Object sender,EventArgs e)      在System.ComponentModel.PropertyDescriptor.OnValueChanged(Object component,EventArgs e)      在System.ComponentModel.ReflectPropertyDescriptor.OnValueChanged(Object component,EventArgs e)      在System.ComponentModel.ReflectPropertyDescriptor.OnINotifyPropertyChanged(Object component,PropertyChangedEventArgs e)      位于C:\ Users \ Juan Luis \ My Dropbox \ Documents \ CodeWebScraper中的Player.DataBaseManager.OnPropertyChanged(PropertyChangedEventArgs e)sin Player \ WebScraperAndPlayer \ Player \ DataBaseManager2.cs:第100行      在C:\ Users \ Juan Luis \ My Dropbox \ Documents \ CodeWebScraper中的Player.DataBaseManager.set_TableNames(List`1值)sin Player \ WebScraperAndPlayer \ Player \ DataBaseManager2.cs:第30行      at C:\ Users \ Juan Luis \ My Dropbox \ Documents \ CodeWebScraper中的Player.DataBaseManager.UpdateTableNames()sin Player \ WebScraperAndPlayer \ Player \ DataBaseManager2.cs:第95行      at C:\ Users \ Juan Luis \ My Dropbox \ Documents \ CodeWebScraper中的Player.DataBaseManager.ExecuteNonQuery(String sqlQuery)sin Player \ WebScraperAndPlayer \ Player \ DataBaseManager2.cs:line 336      at WebScraperAndPlayer.DataBaseEditor.deleteTableButton_Click(Object sender,EventArgs e)在C:\ Users \ Juan Luis \ My Dropbox \ Documents \ CodeWebScraper sin Player \ WebScraperAndPlayer \ BuilderForm2 \ Data \ DataBaseEditor.cs:第90行      在System.Windows.Forms.ToolStripItem.RaiseEvent(Object key,EventArgs e)      在System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)

3 个答案:

答案 0 :(得分:2)

查看堆栈跟踪

  

位于System.Windows.Forms.BindingsCollection.get_Item(Int32索引)的System.Collections.ArrayList.get_Item(Int32索引),位于System.Windows.Forms.BindingManagerBase.PushData(布尔和成功)

这不是事件连线的问题,在数据绑定中会出现其他问题。

答案 1 :(得分:1)

  

System.EventHandler.Invoke(Object sender,EventArgs e)

那是PropertyChanged(this,e)的电话。它不是异常的原因,你的堆栈跟踪远远超出了这个范围。不幸的是,你没有编写代码,它是Winforms绑定管道的一部分。有些东西搞砸了。

答案 2 :(得分:0)

发现问题。我有一个数据表编辑器,其TablesList属性绑定到数据库管理器对象中的数据表列表。在set访问器中,我检查了表中是否仍然存在该表,如果没有,则编辑器关闭并从数据库管理器中删除数据绑定。因此,虽然.NET的内部循环遍历绑定到TablesList的对象,但其中一个从列表中删除了自己。但是由于编写循环的方式,.NET没有注意到这种变化:

int numLinks = Bindings.Count;
for (int i = 0; i < numLinks; i++) { 
    if (Bindings[i].PushData()) { 
        success = false;
    } 
}

我基本上是从PushData()调用中移除了绑定。我的解决方案是将事件处理程序附加到PropertyChanged事件并检查那里的表列表。显然,.NET用于循环调用事件列表的循环允许您在循环中删除事件。

我想道德将是:永远不要删除从该属性的Binding访问者更新属性的set;但是可以从事件处理程序本身中删除事件处理程序。正确?