0

I started to use Prism (5.0) some days ago and now I run into a problem I cant solve myself.

I used the quickstart "viewswitchingnavigation".

So I have a shell with a navigation and a main panel/region. Navigation region holds some radiobuttons to switch the views that are split into view and viewmodel with a service based model.

View A shows a collection of documents with a button each to open a new view B for this document's details.

A button in this detailview should start a part of code. This code moves some data what takes quite a while since the data need to be parsed. Since the user shouldnt wait for a nonreactiong window I want to show some information about the status of the running code. (Example: Getting data 1/3012, which is updated with each new got data piece). This code gets one piece of data at a time so I could send(?) some information to the view to update the status there (if I knew how)

So.

  1. How to implement the button that starts the "external" code?
  2. How to access the current view (e.g. to change the status shown in a loader or in a textbox like destribed above.
smottt
  • 3,272
  • 11
  • 37
  • 44
Mike F.
  • 48
  • 8
  • There is some information here on StackOverflow about similar: http://stackoverflow.com/questions/1194620/how-do-i-display-progress-during-a-busy-loop What you are wanting to do is not necessarily specific to Prism, it is a general problem with long-running tasks. – dub stylee Feb 03 '15 at 23:50

2 Answers2

1

You could use a BackgroundWorker class which has built-in progress reporting functionality. Alternatively, you could create your own asynchronous data retreiving mechanism by using async / await and Tasks.

For your progress displaying view you could use the State-Based Navigation provided by Prism. You could display an on-top view with a progress bar or text box showing the progress. As usual, the UI elements of the view should be bound to the view model's properties. To update these UI properties you should use Dispatcher.Invoke(), or SynchronizationContext, or similar sync mechanism, because your progress reporting method (or event) will be called by a background thread.

If you could post your code, then my answer could be more specific.

dymanoid
  • 14,771
  • 4
  • 36
  • 64
0

Not exactly sure what you aim for, though here are two options:

Shall the data begin to be fetched when the View/Windows gets loaded? Then your ViewModels have to implement INavigationAware interface and INavigationAware.OnNavigatedTo (and From) Method). You can mark that method as async to be able to use await within it.

public async void INavigationAware.OnNavigatedTo(NavigationContext navigationContext) 
{
    await LongRunningTask();
}

public async Task LongRunningTask()
{
    foreach(var dataChunk in allData) 
    {
        // Status Text is a property which raises OnPropertyChanged when changed and which you databind to a textbox
        StatusText = string.Format("Getting Data {0}", dataChunk.Description);
        await ProcessDataChunk(dataChunk);
    }
}

Or if you want it happen on an user action, you do it via an async ICommand.

private ICommand processCommand;
public ICommand ProcessCommand) 
{
    return processCommand??(processCommand = DelegateCommand.FromAsyncHandler(this.LongRunningTask));
}
Tseng
  • 61,549
  • 15
  • 193
  • 205