You are correct in thinking that it can be specific, each developer finds their own way to make it work because there is no standard for managing busy state of an application. If you're not careful with what you build, like extending the view model base to support busy state functionality at the view model, you might end up not being able to handle scenarios that need busy management that aren't view specific.
That's why the BusyController class isn't responsible for anything other than tracking the number of threads that are currently in use, and sending a notification via the IsBusy property change and a message when that state changes. If your situation requires you to have a control handling busy state independently of the view (for example downloading an image and wanting a busy indicator wrapping the image control while it downloads), tossing an instance of the BusyController on the control class allows you to manage busy state on that control independently of the view.
Control XAML:
<UserControl x:Class="MyApp.MyControl"><UserControl.Resources><helpers:BusyControllerx:Key="BusyController"/></UserControl.Resources><BusyIndicatorIsBusy="{Binding IsBusy, Mode=OneWay, Source={StaticResource BusyController}}"><ImageSource="{Binding ImageSource, Mode=OneWay}"/></BusyIndicator></UserControl>
Code:
publicclass MyControl : UserControl {public MyControl() {this.InitializeComponent();this.BusyController = (BusyController)this.Resources["BusyController"];this.client = new WebClient();this.client.OpenReadCompleted += this.client_OpenReadCompleted; }private WebClient client;publicvoid LoadImage() {this.BusyController.SendMessage(true);this.client.OpenReadAsync(new Uri("http://localhost/SomeHugeImage.png")); }privatevoid client_OpenReadCompleted(object sender, System.Net.OpenReadCompletedEventArgs e) {using (BinaryReader reader = new BinaryReader(e.Result)) {byte[] data = reader.ReadBytes(int.MaxValue); }this.BusyController.SendMessage(false); } }
View XAML:
<Pagex:Class="MyApp.MyPage"xmlns:local="using:MyApp"><Gridx:Name="LayoutRoot"><Grid.ColumnDefinitions><ColumnDefinitionWidth="Auto"/><ColumnDefinitionWidth="Auto"/></Grid.ColumnDefinitions><local:MyControlGrid.Column="0"/><local:MyControlGrid.Column="1"/></Grid></Page>
It keeps you able to use the class in situations that aren't specific to only allowing busy state management on a view. If whatever ends up being built or put into the MVVM Light "core" is too specific, there will undoubtedly be occasions arise where it cannot be used. I had a situation earlier where I needed to be able to manage the busy state of a behavior to ensure it didn't do something while it was already busy doing something else. Granted, it would have been just as easy to add thread synchronization objects to the behavior, but instead I just tossed the busy controller on the instance to let that manage it.
As long as whatever is baked into the MVVM Light "core" doesn't require an artificially imposed construct like a view to make use of it, I think it could be highly used amongst people that use this wonderful framework you've given us.
Thanks for taking the time to read my feedback!
- Jeff