Skip to content

Instantly share code, notes, and snippets.

@jpolvora
Created November 16, 2012 18:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpolvora/4089675 to your computer and use it in GitHub Desktop.
Save jpolvora/4089675 to your computer and use it in GitHub Desktop.
BusyResultWrapper
//Original Idea: http://blog.smoothfriction.nl/archive/2012/05/07/silverlight-busyindicator-in-caliburn-micro-pt-2-again.aspx
//A simpler solution:
public interface IBusy
{
bool IsBusy { get; set; }
}
/*
If some ViewModel implements this interface, then there will be a public property
named IsBusy, so we can easilly bind to that property:
*/
public class SomeViewModel: Screen, IBusy
{
public bool IsBusy
{
get { return _isBusy; }
set
{
if (value.Equals(_isBusy)) return;
_isBusy = value;
NotifyOfPropertyChange(() => IsBusy);
}
}
}
/*
The trick is to create a Wrapper class that decorates the SequentialResult of CM:
*/
internal class BusyResultWrapper : IResult
{
private readonly SequentialResult _inner;
private IBusy _busy;
public BusyResultWrapper(SequentialResult inner)
{
if (inner == null)
throw new ArgumentNullException("inner");
_inner = inner;
}
public void Execute(ActionExecutionContext context)
{
_busy = context.Target as IBusy;
if (_busy != null)
_busy.IsBusy = true;
_inner.Completed += OnCompleted;
_inner.Execute(context);
}
public event EventHandler<ResultCompletionEventArgs> Completed;
public void OnCompleted(object sender, ResultCompletionEventArgs resultCompletionEventArgs)
{
_inner.Completed -= OnCompleted;
if (_busy != null)
_busy.IsBusy = false;
var handler = Completed;
if (handler != null) handler(sender, resultCompletionEventArgs);
}
}
//In the view, insert a BusyIndicator control named IsBusy:
<toolkit:BusyIndicator x:Name="IsBusy">
Some content here...
</toolkit:BusyIndicator>
/* to ensure CaliburnMicro will apply convention for binding the busy indicator, add a convention overriding the Configure of bootstrapper: */
//your bootstrapper class
protected override void Configure()
{
ConventionManager.AddElementConvention<BusyIndicator>(BusyIndicator.IsBusyProperty, "IsBusy", null);
Coroutine.CreateParentEnumerator = enumerator =>
{
var sequ = new SequentialResult(enumerator);
return new BusyResultWrapper(sequ);
};
}
/*Don't forget to set the target of ActionExecutionContext to the ViewModel that implements IBusy before calling the BeginExecute method of Coroutine class*/
public void SomeCommand()
{
var context = new ActionExecutionContext {Target = this};
Coroutine.BeginExecute(SaveData(), context, (s, e) => Refresh());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment