How to block user interface during asynchronous operations in WPF

We have a WPF application (actually a VSTO WPF application). Some controls have several elements that, when clicked on, load data from the web service and update the user interface. Right now, we are executing these web requests synchronously, blocking the UI thread until the response returns. This prevents the user from clicking on the application while loading data, which potentially puts it in an invalid state for processing data when it is returned.

Of course, the application stops responding if the request takes a long time. Ideally, we would like the cancel button to be active during this time, but nothing else. Is there any reasonable way to do this, or do we have to switch requests to asynchronous execution using a background worker and write something that disables all controls except the cancel button when the request is executed?

edit: for the actions that we are already expecting, it will work for a long time (file upload, etc.), we open the progress dialog box. The fact is that you expect the action to be quite fast (a maximum of a couple of seconds), but from time to time it takes longer. In these circumstances, the instant blink of an entire window is a little distracting.

+4
source share
5 answers

Your managed controls should be bound to commands, and commands should have CanBeExecuted return false when a background job is running. If you do this, the controls bound to these commands will automatically turn off and on.

You can avoid duplication of a large amount of code by creating a class of commands that implements verification of the background task during execution, and then outputs all your commands (except the cancel command, of course) from this class.

+4
source

While you are making your asynchronous request in a separate thread, show the Modal Dialog dialog box with the Cancel button (and possibly a progress bar or some other activity indicator).

Thus, the user cannot interact with the main user interface, and they still receive feedback, something is happening ... and the ability to cancel it.

+1
source

One way would be to make a translucent canvas over parts of the user interface that are not available while waiting for a response, and in the center is a message with a cancel button.

+1
source

Silverlight Toolkit has a BusyIndicator control. The toolkit is open source, so you can easily port it to WPF.

It disables and selects everything in the area to which it is assigned when setting its IsBusy property to true either in the code or binding it to the model. The following is used:

 <ctl:BusyIndicator> <StackPanel x:Name="myDataArea"> <Button Content="Load Data" /> <DataGrid x:Name="myDataGrid" /> </StackPanel> </ctl:BusyIndicator> 
+1
source

I can’t come up with a simple way, except to disable all controls except “cancel”.

Having said that, a more experienced user can give it if you display the “work” dialog or progress using only the cancel button.

You can use this dailog to display useful information about the progress of web requests and any error messages that may return.

0
source

Source: https://habr.com/ru/post/1304359/


All Articles