Generally Preferred Method for a 'Wait' Screen using MVVM and Silverlight

这一生的挚爱 提交于 2019-12-04 04:03:53

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.

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" />

You could use the Mediator prototype that Josh Smith created to have a loosely coupled messaging system from the VM to the V. The VM could push out a message that it is "busy", with the view subscribing to this "IsBusy" message.

The view could then show the correct dialog until a "IsNotBusy" message is received.

Another option is to pass to the ViewModel in the constructor some interface like IDialogProvider that has methods to show a dialog. The implementation of this provider will be view specific but at least the view model only knows about the interface and not a concrete implementation.

public interface IDialogProvider
{
 void ShowErrorMessage(string message);
}

Mediator Prototype

标签