Created
November 16, 2012 18:29
-
-
Save jpolvora/4089675 to your computer and use it in GitHub Desktop.
BusyResultWrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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