Hi all,
I have some problems with the latest version of CSLA 2.1.4 wich I didn't have with CSLA 2.1.3. I've tracked down the problem and it's the order of execution inside RemoveItem at BusinessListBase.vb. In 2.1.4 this is the code:
' when an object is 'removed' it is really
' being deleted, so do the deletion work
Dim child As C = Me(index)
MyBase.RemoveItem(index)
CopyToDeletedList(child)
End Sub
but in previous versions the CopyToDeletedList was executing before RemoveItem. I guess that there is a good cause for swapping those lines but this change broke my code. This is because I've some GUI elements that are listening for the ListChanged / ItemRemoved event wich is fired by RemoveItem(index). Then my code checks for the EditableCollection.IsDirty value but it's inconsistent because CopyToDeletedList(child) has not been executed yet (IsDirty depends on DeletedList count). In a few words, what I want is to enable the Save button if the user removes an item from the EditableCollection.
Any thoughts on this issue? Should I implement this in other way..?
Regards
Jacobo
I have the same problem. Rocky explains in the change log why it was changed but this may be an unexpected effect.
Ross
Hmm, that's unfortunate...
I can't just put the code back though, because the original problem was serious - triggering a Reset event on every remove, which can be very expensive, and was technically wrong in any case.
What might work, is the following sequence:
The only catch to this, is that for a brief time the object will be in deletedList, but it won't be marked for deletion.
Perhaps most notably, when your UI code is handling the ListChanged event, the collection's IsDirty will be true, but at that instant the to-be-deleted child won't be fully in its deleted state.
Alternately, perhaps I could revert the BLB code, but change BB so its DeleteChild() implementation doesn't trigger a call to OnUnknownPropertyChanged. That would prevent the child from raising its changed event, thus preventing BLB from raising the ListChanged(Reset) event.
I don’t have control over the ListChanged event being
raised – that comes from BindingList<T> - so I don’t think
there’s any realistic way for me to suspend the events, no.
Rocky
From: ajj3085
[mailto:cslanet@lhotka.net]
Sent: Monday, March 12, 2007 7:21 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Problem removing item with 2.1.4
Is there a way to suspend the raising of events until both
operations have completed, then after both have completed, raise the required
events?
RockfordLhotka:I don’t have control over the ListChanged event being raised – that comes from BindingList<T> - so I don’t think there’s any realistic way for me to suspend the events, no.
Yes, that appears to work – glad you brought up that idea!!
Rocky
From: tetranz
[mailto:cslanet@lhotka.net]
Sent: Monday, March 12, 2007 11:55 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Problem removing item with 2.1.4
I'm not in a convenient spot to
try this right now but wouldn't something like this work? Isn't it the
listchange here that bubbles up to the BindingSource?
C child = this[index];
this.RaiseListChangedEvents = false;
base.RemoveItem(index);
this.RaiseListChangedEvents = true;
CopyToDeletedList(child);
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
Ross
RockfordLhotka:
I don’t have control over the ListChanged event being
raised – that comes from BindingList<T> - so I don’t think there’s
any realistic way for me to suspend the events, no.
Yes, I wasn’t thinking – rub it in, rub it in J
I’ve made the change and the code is in svn (http://www.lhotka.net/cslacvs/viewvc.cgi/trunk/).
In my test harness it appears to solve both the original and new problem.
Rocky
From: ajj3085
[mailto:cslanet@lhotka.net]
Sent: Monday, March 12, 2007 1:07 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Problem removing item with 2.1.4
I thought you could use the RaiseListChangedEvent property
to suspend the raising of events in a BindingList<T>?
Don’t mind me, I’m just giving you a hard time J
From: ajj3085
[mailto:cslanet@lhotka.net]
Sent: Monday, March 12, 2007 2:05 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: Problem removing item with 2.1.4
Didn't mean to rub it in... just hit reply before seeing if
anyone else had posted a similar answer... so bad posting etiquette on my part.
Thanks everybody for your time and support with this issue, the current version it's working now for me. And sorry for being picky but shouldn't we preserve the RaiseListChangedEvents value ? Like this:
Protected
Overrides Sub RemoveItem(ByVal index As Integer)' when an object is 'removed' it is really
' being deleted, so do the deletion work
Dim child As C = Me(index)
Dim OldRaiseListChangedEvents As Boolean = Me.RaiseListChangedEvents
Me.RaiseListChangedEvents = False
Try
MyBase.RemoveItem(index)
Finally
Me.RaiseListChangedEvents = OldRaiseListChangedEvents
End Try
CopyToDeletedList(child)
OnListChanged(New ListChangedEventArgs(ListChangedType.ItemDeleted, index))
End Sub
Jacobo
Yes, very good point!
Rocky
From: amselem
[mailto:cslanet@lhotka.net]
Sent: Monday, March 12, 2007 4:52 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: RE: Problem removing item with 2.1.4
Thanks everybody for your time and support with this issue, the current version
it's working now for me. And sorry for being picky but shouldn't we preserve
the RaiseListChangedEvents value ? Like this:
Protected Overrides Sub RemoveItem(ByVal
index As Integer)
' when an object is 'removed' it
is really
' being deleted, so do the deletion work
Dim child As C = Me(index)
Dim OldRaiseListChangedEvents As Boolean = Me.RaiseListChangedEvents
Me.RaiseListChangedEvents = False
Try
MyBase.RemoveItem(index)
Finally
Me.RaiseListChangedEvents = OldRaiseListChangedEvents
E nd Try
CopyToDeletedList(child)
OnListChanged(New
ListChangedEventArgs(ListChangedType.ItemDeleted, index))
End Sub
Jacobo
Just to continue the pain one more step , we should only generate our own event if RaiseListChangedEvents was true.amselem:sorry for being picky but shouldn't we preserve the RaiseListChangedEvents value?
ajj3085:tetranz,The code as is will work fine; OnListChanged respects the value of RaiseListChangedEvents, which Rocky has restored to whatever value at the end.
ajj3085:tetranz,
The code as is will work fine; OnListChanged respects the value of RaiseListChangedEvents, which Rocky has restored to whatever value at the end.
You should look at the current (3.0.3) code, because I believe
this is addressed in that version.
Rocky
From: stephen.fung
[mailto:cslanet@lhotka.net]
Sent: Monday, December 17, 2007 7:37 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Problem removing item with 2.1.4
Hi,
Maybe we're talking about different things, but this statement doesn't seem to
match my experience with CSLA 3.0.2.
Using the .NET Reflector to look at the source code for BindingList<T>,
it doesn't look like OnListChanged respects the RaiseListChangedEvents
property.
Modifying the code to respect RaiseListChangedEvents in
BusinessListBase.SetItem and RemoveItem before calling OnListChanged solved a
problem for me related to this.
if(this.RaiseListChangedEvents)
OnListChanged(new
ListChangedEventArgs(ListChangedType.ItemDeleted, index));
Copyright (c) Marimer LLC