This blog will describe some of the learning experiences that I have with .NET, some personal projects that I'm working on, and whatever other topics tickle my fancy.
My Blog Links
Friday, March 26, 2004
Now that the ArrayList fires events, what about when the data within one of its contained components changes. Any UI you have (or any other listener for that matter) would need to be updated. So, we need events fired when that happens too. The problem is that the ArrayList doesn't know when you've changed the data object itself because lots of time, you call it like this:
myArrayList[index].Name = "new name";All the ArrayList knows is that the object has been accessed, but not why. So, the object itself needs to be able to fire the change event. To do this, we exposed a public ArrayItemsChanged event and OnArrayItemsChanged method, so that it can be called from the object not just within the EventedArrayList.
Note: I tried using a static ArrayItemsChanged event on the EventedListItem class itself so that any instance of it could fire this event. But, then the listeners list would be static too, so any item change would fire the event to all listeners regardless of what instance of the ArrayList is was in. That wasn't exactly what I wanted because it could cause a lot of "noise" events to be fired, and the handlers would need more intelligent code to figure out whether or not it cared about that particular object's event. I decided to let the ArrayList manage the listener list because then you'd only have to connect to the right instance of the ArrayList rather than each individual instance of an object that you wanted to listen to.
So, now the problem was for an object to fire the event, it needs a pointer back to the appropriate EventedArrayList that it belongs to, so I created the following interface and class to handle that:
The EventedListItem keeps track of its parent EventedArrayList, so that it knows which ones to use to fire events through. It supports a list of parents that this item has been added to, that way you can put this item in multiple EventedArrayLists. If it hasn't been associated to an ArrayList yet, then it doesn't fire any events.
Also, any item that wants this functionality needs to either implement the IEventedListItem interface or derive from EventedListItem (which contains the default implementation for that interface). I implemented it through an interface, in case you have issues where you need to derive from a specific base class. And, provided the base implementation for the cases where you can derive from it (in this case, no additional coding needed on your end).
Note: If multiple class derivation is an issue for your class, then you must implement IEventedListItem on your class rather than deriving directly from EventedListItem (you can copy its code for your implementation, if you want the same functionality though).
Now that we have these two classes (EventedArrayList and EventedListItem), we need to associate them. I did this in the EventedArrayList class. The OnArrayItemsAdded method associates any newly added items with this EventedArrayList. If the item does not implement IEventedListItem then it's not associated.
As you can see, we also have a corresponding DisassociateItemsWithArrayList that's called from OnArrayItemsRemoved to get rid of any existing associations.
Now, on to how we handle these new events...
You can download the full sample code from GotDotNet or look at it online and report bugs at the workspace.
Comments: Post a Comment