问题
I have a situation where I need to know when an item is going to be added/removed/modified in the collection.
I tried by inheriting BindingList in a class that will trigger these events, however the "adding" event doesn't work. The only way I found it working is by overriding EndNew() method, however I don't find a way to get which object is going to be added in this method (if someone has a solution for this, it's ok too!).
So built a totally new class which inherits from same interfaces/class of BindingList and implemented everything (I didn't inherit, however, ICancelAddNew).
I bound it through databindings to my listbox and I find out that nothing works (listchanged events neither listchanging events). How can I simulate BindingList behavior on a listbox?
Any suggestion heavily appreciated, I don't have any other ideas for a workaround
EDIT 1:
This is my collection: http://pastie.org/1978601 And this is how I bind the collection to the ListBox
SpellCasterManager.CurrentProfile.ButtonsMacro.ListChanged += new ListChangedEventHandler(ButtonsMacro_ListChanged);
SpellCasterManager.CurrentProfile.ButtonsMacro.ListChanging += new Expand.ComponentModel.ListChangingEventHandler(ButtonsMacro_ListChanging);
gumpButton.DataBindings.Add("Value", SpellCasterManager.CurrentProfile.ButtonsMacro, "GumpIndex", false, DataSourceUpdateMode.OnPropertyChanged);
Actually under subscribed events there is just a MessageBox.Show("bla");
回答1:
Your collection won't detect property changes in an existing item because it doesn't hook into the item's property changed events as it is added to the collection.
BindingList<T>
does listen to PropertyChanged on your item and does fire a ListChanged event when an item is added to the BindingList and it does include the index at which is is added. Try it in a test app without WinForms.Adding an existing item is not the same as AddNew(). The AddingNew event is only called when AddNew() is called and allows you to supply the new instance.
When WinForms is involved, things get more complicated. There is the CurrencyManager to think about and also BindingSource. If no events are firing at all then check to see if you are using the CurrencyManager/BindingSource you think you are.
I don't think anything in the framework uses INotifyPropertyChanging, only the original INotifyPropertyChanged. You might want to use Reflector on BindingList to see how the hooking is done and then try to incorporate INotifyPropertyChanging if your item supports it.
回答2:
Did you follow MSDN guidelines? Your collection class should extend CollectionBase
and implement IBindingList
- and that should be fine.
Also, you might want your collection item to implement IEditableObject
in order to support *Edit
operations. This however is not required - more importantly, your collection item should have a way to notify parent collection when it changes (either by following code provided on MSDN, or using for example INotifyPropertyChanged).
You can find working binding sample implementing custom CustomersList
on IBindingList doc page (Customer
class can be found on IEditableObject doc page).
回答3:
After getting clear idea of what you are looking for i will suggest following things
Here is a great undo framework which provides lot of functionality. http://undo.codeplex.com/
Here is sample, http://blogs.msdn.com/b/kirillosenkov/archive/2009/07/02/samples-for-the-undo-framework.aspx
And in your case, instead of trying to hook on adding/editing events, it's better to track after added/modified/deleted event if you store their initial state. So if the item was removed, in your previous state you will have the item already if you started tracking from the start state of your program.
来源:https://stackoverflow.com/questions/6105102/create-a-custom-collection-like-bindinglist-that-works-with-listbox-to-create-a