3

How can I display a Message box or some other similar notice show while the application is busy in the background, similar to this mockup:

enter image description here

murmansk
  • 845
  • 2
  • 11
  • 28

2 Answers2

8

There is a Busy Indicator in the WPF Extended Toolkit which I've used quite a lot:

Screenshot of the busy indicator

The toolkit is conveniently available through NuGet which makes it really easy to add it as a reference to your project. I've personally used it (along with many of the other useful controls in that toolkit) in almost all of my recent WPF projects.

To use it, surround your controls in the XAML code with the busy indicator:

<extToolkit:BusyIndicator ...>
    <Grid>
        <Button Content="Click to do stuff" />
        <!-- your other stuff here -->
    </Grid>
</extToolkit:BusyIndicator>       

Then you just have to set the IsBusy property to true when you want the popup to appear and false when it should be hidden. In a proper MVVM architecture, you would typically databind the property in XAML to a property in your viewmodel which you then set to true/false accordingly:

<extToolkit:BusyIndicator IsBusy="{Binding IsBusy}" >

But if you aren't using MVVM, you can of course set it manually from your code behind, typically in the button click handler:

Give the control a name to be able to refer to it from code:

<extToolkit:BusyIndicator x:Name="busyIndicator" >

And then, in your xaml.cs file:

void myButton_Click(object sender, RoutedEventArgs e)
{
    busyIndicator.IsBusy = true;
    // Start your background work - this has to be done on a separate thread,
    // for example by using a BackgroundWorker
    var worker = new BackgroundWorker();
    worker.DoWork += (s,ev) => DoSomeWork();
    worker.RunWorkerCompleted += (s,ev) => busyIndicator.IsBusy = false;
    worker.RunWorkerAsync();
}
Isak Savo
  • 34,957
  • 11
  • 60
  • 92
4

If you code MVVM it's easy:

1.)Add a Boolean Flag "IsBusy" to your ViewModel with change notification.

public bool IsBusy {get {return _isBusy;} set{_isBusy=value;OnPropertyChanged("IsBusy");}}
private bool _isBusy;

2.) Add two events to your Command "Started" and "Completed"

public event Action Completed;

public event Action Started;

3.) In your ViewModel, subscribe to those events and set the busy status.

LoadImagesCommand.Started += delegate { IsBusy = true; };
LoadImagesCommand.Completed += delegate { IsBusy = false; };

4.) In your Window, you can now bind to that status

<Popup Visibility="{Binding Path=IsBusy,Converter={StaticResource boolToVisibilityConverter}}"/>

Note that for the last step you must instanciate the boolToVisibilityConverter, so:

5.) Add the following to any loaded Resource Dictionary:

<BooleanToVisibilityConverter x:Key="boolToVisibilityConverter"/>

That's it! You can fill your Popup with the life you want...

Sebastian Edelmeier
  • 4,095
  • 3
  • 39
  • 60
  • And if you don't use MVVM it's also easy; this has nothing to do with MVVM. You can do everything you can do with MVVM without as well, it just ends up being less maintanable. – H.B. Jan 11 '12 at 08:28
  • I dont think this MVVM stuff is going into my brain , I am quite new to WPF, is their any easy method using only .caml and .xaml.cs file – murmansk Jan 11 '12 at 09:11
  • Using xaml.cs, you can do that. Only that this will make your UI a bit more status-laden, but basically you can define a Popup in your XAML, then use Popup.Visibility=Visibility.Hidden / Visible to hide or show your popup. – Sebastian Edelmeier Jan 11 '12 at 11:30
  • @murmansk: .caml? Anyhow, I hope you know that you have to do your work on a background thread and that you can only access UI elements from that thread via the UI thread's Dispatcher. Be warned, otherwise you'll be back asking "why isn't my busy indicator showing" (you're working in the UI thread and therefore the UI isn't updating) and "why is there an exception when I update the UI" (you are touching UI components from a different thread). –  Jan 11 '12 at 14:10