Reputation: 15715
I thought that if I have this code:
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) PropertyChanged(this, e);
}
and the PropertyChanged
event wasn't hooked, ProeprtyChanged
would be null
, but I'm getting a PropertyChanged
that is not null and whose _invocationList
member is null
and whose _invocationCount
member is 0. This (I think) is causing an ArgumentOutOfRangeException when I invoke PropertyChanged(this, e)
. Any idea where could the problem be?
This is my stack trace from the OnClick
event:
at System.Collections.ArrayList.get_Item(Int32 index) at System.Windows.Forms.BindingsCollection.get_Item(Int32 index) at System.Windows.Forms.BindingManagerBase.PushData(Boolean& success) at System.Windows.Forms.PropertyManager.OnCurrentChanged(EventArgs ea) at System.Windows.Forms.BindToObject.PropValueChanged(Object sender, EventArgs e) at System.EventHandler.Invoke(Object sender, EventArgs e) at System.ComponentModel.PropertyDescriptor.OnValueChanged(Object component, EventArgs e) at System.ComponentModel.ReflectPropertyDescriptor.OnValueChanged(Object component, EventArgs e) at System.ComponentModel.ReflectPropertyDescriptor.OnINotifyPropertyChanged(Object component, PropertyChangedEventArgs e) at Player.DataBaseManager.OnPropertyChanged(PropertyChangedEventArgs e) in C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 100 at Player.DataBaseManager.set_TableNames(List`1 value) in C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 30 at Player.DataBaseManager.UpdateTableNames() in C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 95 at Player.DataBaseManager.ExecuteNonQuery(String sqlQuery) in C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\Player\DataBaseManager2.cs:line 336 at WebScraperAndPlayer.DataBaseEditor.deleteTableButton_Click(Object sender, EventArgs e) in C:\Users\Juan Luis\My Dropbox\Documents\CodeWebScraper sin Player\WebScraperAndPlayer\BuilderForm2\Data\DataBaseEditor.cs:line 90 at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
Upvotes: 0
Views: 905
Reputation: 15715
Found the problem. I had a data table editor that had a TablesList
property bound to a list of data tables in a data base manager object. In its set
accessor I checked to see if the table still existed in the list and if it didn't the editor closed and removed the data binding from the data base manager. So, while the internals of .NET were looping through the objects bound to TablesList
, one of them removed itself from the list. But .NET doesn't notice this change because of the way the loop is written:
int numLinks = Bindings.Count;
for (int i = 0; i < numLinks; i++) {
if (Bindings[i].PushData()) {
success = false;
}
}
I was basically removing the binding from inside the PushData()
call. My solution was to attach an event handler to the PropertyChanged
event and check the table list there. Apparently whatever loop .NET uses to loop through the invocation list of events let you remove an event while in the loop.
I guess the moral would be: Never remove a Binding
that updates a property from the set
accessor of that property; but is OK to remove an event handler from the event handler itself. Right?
Upvotes: 1
Reputation: 941208
System.EventHandler.Invoke(Object sender, EventArgs e)
That was the PropertyChanged(this, e) call. It isn't the cause of the exception, your stack trace went well beyond this. Unfortunately into code you didn't write, it's part of the Winforms binding plumbing. Something is screwed up with the binding.
Upvotes: 1
Reputation: 241585
Look at your stack trace
at System.Collections.ArrayList.get_Item(Int32 index) at System.Windows.Forms.BindingsCollection.get_Item(Int32 index) at System.Windows.Forms.BindingManagerBase.PushData(Boolean& success) at
This isn't a problem with the event wiring, something else is messed up in your data binding.
Upvotes: 2