On the last line of this method it calls
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, child, index));
Which raises the collection change event. However it is passing NotifyCollectionChangedEventArgs containing NotifyCollectionChangedAction.Remove. I believe that this causes Wpf to remove the item from the bound Listbox. Surely this should be NotifyCollectionChangedAction.Replace.
I ammended CSLA 4.3.10 source and it certainly solved my problem. Of course, I dont want to use this unless the fix is properly sanctioned
It is a bug. Added to bugtracker:
Jonny
Oh life is not as simple as we would like. It turns out that NoifyCollectionChangedEventArgs constructor will not accept an Action of NotifyCollectionChangedAction.Replace, it will only accept Add, Remove and Reset. In my testing an exception was thrown that my UI framework was swallwoing (I didnt see it unitl i was looking at a log).
I think that you can either leave out the notification altogether and the developer has to refresh the binding or use the Reset action, preferable. If you change it to Reset be sure to set the Index to -1. I didnt see SetItem failing visually as I had raised a PropertyChanged event on the BusinessObject's collection property as well in my initail attempt to make it work.
Microsoft documentation can be misleading (aka lying) :-)
Simon.
Another possibility:
Call remove on old child when raiselistchangedevents is false and call setitem after it's reset to true. (reverse order from today).
Then the item ends up in the DeleteList not something that I want. In my case I am replacing the item with a modified version of itself.
The events raised should match those raised by a standard ObservableCollection<T>. Whatever we want or don't want is immaterial - only the standard behavior matters.
It should be easy enough to monitor the events raised by a standard ObservableCollection and mirror them. In fact, I thought that's what I did with this implementation - but perhaps I did make a mistake in the code.
It is a bug:
Using ObservableCollection<T>
Action:Replace, NewStartingIndex:1, OldStartingIndex:1
Using Csla.BusinessListBase<C, T>
Action:Remove, NewStartingIndex:-1, OldStartingIndex:1
Code:
var list = ItemList.New();
list.CollectionChanged += (o, e) =>
{
Console.WriteLine("Action:{0}, NewStartingIndex:{1}, OldStartingIndex:{2}", e.Action.ToString(), e.NewStartingIndex, e.OldStartingIndex);
};
list[1] = new Item() {Id = 5, Name = "XYZZY"};
Console.ReadLine();
Changing the sequence as described will make the correct listchanged event to occur.
Changes checked in to repository for Csla 4.3.x and 4.5
Copyright (c) Marimer LLC