tj94
tj94

Reputation: 61

Doing work while a ContentDialog is open

I'm making an app for Windows 10 Mobile Enterprise using the UWP frameworks. I have a number of files to save to disk in a loop, and I want to show a popup ProgressBar that blocks the user while the files are being saved. I want to update the ProgressBar every loop iteration, and remove it at the end.

I figured I could make a custom ContentDialog containing a ProgressBar, and show the ContentDialog at the start. I'm confused how to do this though, because the ContentDialog's ShowAsync() method blocks while dialog is open.

My guess is that I must either do the ShowAsync() or the file loop in a new thread/task/whatever. Is there a best practices sort of approach for this?

Note - the progress bar cannot, according to the requirements just go inside the current page. It has to be a popup of some sort that blocks the user until it is closed by the code.

Upvotes: 0

Views: 939

Answers (2)

P-Day
P-Day

Reputation: 1

A late reply but if anyone run into this in the future another potential solution is to just block the rest of the page with your progress bar. If the contents of your view are contained in a single grid, you can place the progress bar as the last element in the grid which causes it to be presented on top of all the other UI elements. You will likely have to wrap the ProgressBar with it's own Grid so that you can center the ProgressBar on the page, but use the grid to overlay and effectively disable the rest of the page while the ProgressBar is running.

I do something similar with loading rings in my apps:

<Grid
    Grid.ColumnSpan="3"
    Background="Black"
    Visibility="{x:Bind ViewModel.IsLoading, Converter={StaticResource VisibleWhenTrueConverter}}"
    Opacity="0.6">
    <ProgressRing
        Width="100"
        Height="100"
        IsActive="{x:Bind ViewModel.IsLoading}" />
</Grid>

Upvotes: 0

Martin Zikmund
Martin Zikmund

Reputation: 39082

ContentDialog is actually not really suitable for this scenario. The problem is that ContentDialog represents a modal dialog, which means the app window is blocked until the dialog is closed by the user. The Task ShowAsync() method is built in such way that you can wait for the user to perform the content dialog action and you cannot open the dialog on any other thread than UI.

You have three possible solutions:

  • Add a kind of "status bar" into your app, that will indicate an action is in progress and when the user clicks it, show a Popup with progress details (which can be dismissed by clicking elsewhere, but the user is able to show it again from the "status bar")
  • Implement a Secondary view, which will show the progress of the operation. You can find more information on Secondary views in the documentation. Also note that the secondary view has a different UI thread, so you will have to keep that in mind when updating its UI (you will have to use that view's Dispatcher)
  • Create some a "fake window" within your app, which will be just a UI element above all other UI. This will however not feel right, so I would suggest against this approach.

Upvotes: 1

Related Questions