I'm moving along on a small proof of concept application. This is mostly to beef up my MVVM skills within Silverlight. I came across an interesting problem today that I could not figure how to solve the MVVM way. I wasn't successful finding anything relevant during search either.
So on to the problem, I have a simple business type application with a database back end. I have a login view and a view model attached that will perform the login and report success or failure. No problem. What I haven't been happy with just yet is a way to report a wait screen to the user. So given my login screen, the user click Login and there's a delay of a couple of seconds while the database chatting is done. I'd like to report this and disable any interaction until the call is completed.
I had a couple of ideas. First, bind the Cursor property to the viewmodel and the VM can set an IsBusy property to true. Problem with this is that I cannot seem to bind to Cursor for the UserControl (Visual Studio says AG_E_RUNTIME_MANAGED_UNKNOWN_ERROR
).
Second idea is to have a wait screen. You know, the little gears turning or whatever animation you want. And that's fine, but it's not real clear to me how I could make the view toggle this through the model through the Xaml. I know I could definitely hook up events and handle this in code. Maybe that's the way to go? Seems to against the MVVM grain just a bit.
Would be interested in more ideas on how to handle this.
Thank you.
I think others might be "overthinking" this one...
I would recommend using the BusyIndicator in the Silverlight toolkit.
Simple XAML:
<toolkit:BusyIndicator Name="busyBoy" IsBusy="true" BusyContent="Fetching Data..." Margin="6,248,0,0" />
We've ended up using a service for processing long running requests. The service takes the workload as a delegate, and then passes it off to a BackgroundWorker, while also opening our "Please wait" view.
This works well as it allows us to control long running processes across all our ViewModels in the same way, with a fairly simple interface.
You could have events coming from the ViewModel update the View when you need a delay, but then you need to have this code in all your ViewModels, and not in a single class that can be maintained more easily.
EDIT A service is just a class that's registered within your IOC container, and can be used by your ViewModels.
public interface IProcessingService
{
void Process(Action<BackgroundWorker> action);
void Process(Action<BackgroundWorker> action,
Action<RunWorkerCompletedEventArgs> finish);
}
Using this your ViewModel could implement something like this.
{
var processingService = container.Resolve<IProcessingService>();
processingService.Process(worker =>
{
worker.ReportProgress(0, "Please wait...");
// Do work here
worker.ReportProgress(50);
// Do more work
worker.ReportProgress(100);
});
}
This way all your code for displaying the progress notification is in the class that implements IProcessingService
and your views remain free of any code that directly controls a view or any UI elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With