BusyAnimation during save?

BusyAnimation during save?

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


Devman posted on Thursday, November 19, 2009

Hi,

I've hooked up the BusyAnimation IsRunning property to the IsBusy property of my CslaDataProvider/BO. The animation runs as the object is retrieved, so far so good.

However is it possible to have the animation running whilst saving/undo changes to the BO? I would have thought the IsBusy property would be true during the save/undo process, but it is not :(


I have a checkbox bound to IsBusy (where its datacontext is the CslaDataProvider) to see the status of the property. Ive also removed "BindsDirectlyToSource=True" from the binding and the checkbox never gets checked.

<CheckBox IsEnabled="False" IsChecked="{Binding Path=IsBusy,Mode=OneWay, BindsDirectlyToSource=True}" Content="IsBusy"/>

Any thoughts?

Best Regards
David

RockfordLhotka replied on Friday, November 20, 2009

In WPF the save operation is synchronous, so this won't work. In SL the save operation is async (by definition), so it should work fine.

In WPF when using a ViewModel base class you can choose to use sync or async save, and if you choose async then you can use BusyAnimation.

Devman replied on Monday, November 23, 2009

I haven't got round to looking at the MVVM changes for Csla yet, but it looks the way to go :-)

Cheers Rocky

Roel replied on Monday, January 04, 2010

Hi Rocky,

When CSLA 3.8 was released, I tried to implement one of our screens with a ViewModel. As some of our screens have a lot of data that needs to be loaded, we preferably use asynchronous calls. Normally we let the CslaDataProvider handle that stuff, but with the ViewModel, we got the option to use DoRefresh or BeginRefresh. We went with the BeginRefresh because we want to load the data asynchronously.

Next to changing the Mouse cursor to a wait cursor, we would like to show the BusyAnimation. If I bind the BusyAnimation.IsRunning to the ViewModel.IsBusy property, the BusyAnimation won't show, even though I can see the property changes correctly and the PropertyChanged events are fired (I added diagnostics:PresentationTraceSources.TraceLevel=High to the binding)

Any ideas why this could possibly not work for us?

triplea replied on Monday, January 04, 2010

I just tried this with the latest version (3.8.2 beta) and it works fine. 2 things I can think of is maybe your binding path is wrong or maybe visibility is set wrong. It probably does not help but here is the XAML with the Path that works for me:

<csla:BusyAnimation Name="BusyAnimation" Foreground="Wheat" IsRunning="{Binding Path=IsBusy}" />

Roel replied on Tuesday, January 05, 2010

This is my xaml, nothing different from yours.

csla:BusyAnimation Grid.Column="1" Grid.Row="1" Height="30" Width="30" IsRunning="{Binding Path=IsBusy}" />

It looks like the asynchronous call isn't that asynchronous. The application still enters a not responding state while executing the factory method on my BO. In the ViewModel I call BeginRefresh with the correct parameters. The static factorymethod gets called, and calls the DataPortal.Fetch method. Since the BeginRefresh requires a callback delegate, I call the DynamicInvoke of that delegate with a new DataPortalResult with the result of the DataPortal.Fetch call as parameter.

RockfordLhotka replied on Tuesday, January 05, 2010

BeginRefresh() should call your async factory, not the sync factory. On .NET your async factory must call BeginFetch(), not Fetch() on the data portal. In other words, it is up to you to ensure that the factory is implemented correctly to be async.

The ViewModel will, by default, always call BeginSave() and so the save operation should be async.

There is no async undo/cancel operation - that's a near-impossibility, since it would only work if you unbound the entire object graph from the UI first, and people will forget to do that and crash their apps, so I have chosen not to go down that road.

Of course you can always override DoCancel() in your viewmodel and make it async. Just remember that you must completely unbind the object graph from the UI first, then rebind it after the cancel is complete - which seems very messy to me.

Or I suppose you could clone the object graph, do the undo on the clone, then set Model to the clone. That'll reduce performance, but would allow the undo operation to run on a background thread.

Roel replied on Wednesday, January 06, 2010

Thanks Rocky!

Copyright (c) Marimer LLC