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
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!
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.
Ok, thanks. Any other thoughts on improving the speed of the CancelEdit() operation on a large collection (short of reducing the collection size itself ;) ?
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.
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...
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.
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