Disabling BusinessListBase events when cancelling changes

Disabling BusinessListBase events when cancelling changes

Old forum URL: forums.lhotka.net/forums/t/3108.aspx


amselem posted on Wednesday, June 27, 2007

Hi all,

In these threads they conclude that we should disable the BindingSource.RaiseListChangedEvents before calling BusinessListBase.CancelEdit for avoiding slow performance when undoing changes:

 http://forums.lhotka.net/forums/thread/3149.aspx
 http://forums.lhotka.net/forums/thread/3727.aspx

I'd like to standarize this behavior to all my BLB so I derived it and overrided BusinessListBase.UndoChanges :

Protected Overrides Sub UndoChanges(ByVal parentEditLevel As Integer)
   Dim OldRaiseListChangedEvents As Boolean = Me.RaiseListChangedEvents 
   Me.RaiseListChangedEvents = False
        
   Try
      MyBase.UndoChanges(parentEditLevel)
   Finally
      Me.RaiseListChangedEvents = OldRaiseListChangedEvents
      If OldRaiseListChangedEvents Then
         MyBase.OnListChanged(New System.ComponentModel.ListChangedEventArgs(ListChangedType.Reset, -1))
      End If
   End Try
End Sub

This works fine, the problem is that I did change the framework to make UndoChanges overridable and I don't like that.
Is there any other way to implement this ?  maybe Rocky could add two overridable methods like OnUndoChanges() and OnUndoChangesComplete() ?

Regards,
Jacobo

RockfordLhotka replied on Friday, June 29, 2007

There is already a "complete" method that you can override, but there isn't anything like OnUndoChanges(). That is a fine idea and I'll add it to the wish list.

AaronH replied on Thursday, December 09, 2010

Is there a better solution for this today in the latest version of CSLA?  I have a grid bound to a list of 1000 objects (don't ask) and calling CancelEdit() on the list takes forever (10 seconds).

Thanks!

RockfordLhotka replied on Thursday, December 09, 2010

In CSLA 4 UndoChanges() in BLB sets ERLB to false before the undo. That's not new to CSLA 4 though - the change is in change set 1979 from Jan 14, 2008, which would be around version 3.5.

AaronH replied on Friday, December 10, 2010

Ok, thanks.  Any other thoughts on improving the speed of the CancelEdit() operation on a large collection (short of reducing the collection size itself ;) ?

 

RockfordLhotka replied on Friday, December 10, 2010

Rethink the UI to avoid the need for using n-level undo?

Ultimately there may not be a lot to be done. BeginEdit and CancelEdit aren't cheap operations - especially CancelEdit.

Also, you should try to figure out (using the debugger perhaps) whether it is the cancel operation or the rebinding that is taking so long. When CancelEdit completes it raises events to tell data binding that the entire object graph has changed - basically causing data binding to entirely rebind to the data.

In some UI technologies data binding is the bottleneck more than the CancelEdit operation itself.

If that did turn out to be the case for you, it might be worth switching to a datagrid control that supports virtual/paged loading so the UI would only rebind to the items that are currently visible.

AaronH replied on Friday, December 10, 2010

Good thoughts, thanks.  It is in fact the CancelEdit() method itself that is taking a while.  I removed the binding of the list from the grid to verify.

I tried executing CancelEdit() on a new thread, but unfortunately, it needs to execute via dispatcher on the UI thread, so no luck there either...

RockfordLhotka replied on Friday, December 10, 2010

This may sound odd, but you could try not using CancelEdit, but instead discarding the entire object graph and reloading it from the database. Basically just do a Fetch instead of the CancelEdit and see if that's faster.

AaronH replied on Friday, December 10, 2010

Yeah, I thought about that approach actually.  It is faster to do that, but the problem is, the scroll position of the grid is lost when the new list comes back and I re-bind to it.

Some time ago, I figured out a way to update the bindings with a new list which kept the grid's scroll position, but I remember it being very hackish.

I think I looked into how RootBindingListBase handles that type of behavior, as it successfully updates the binding to a bound object after dataportal_update.

If you have any clever ideas on how to update the bindings after a save operation and keeping the scroll position of the grid, I'm all ears.  Otherwise, I'm afraid I'll just have to re-design my business objects and call BeginEdit() / CancelEdit() only on the participating children objects, as opposed to the root object.

Thanks again!

Copyright (c) Marimer LLC