Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display a busy message over a wpf screen

Tags:

wpf

xaml

Hey, I have a WPF application based on Prism4. When performing slow operations, I want to show a busy screen. I will have a large number of screens, so I'm trying to build a single solution into the framework rather than adding the busy indicator to each screen.

These long running operations run in a background thread. This allows the UI to be updated (good) but does not stop the user from using the UI (bad). What I'd like to do is overlay a control with a spinning dial sort of thing and have that control cover the entire screen (the old HTML trick with DIVs). When the app is busy, the control would display thus block any further interaction as well as showing the spinny thing.

To set this up, I thought I could just have my app screen in a canvas along with the spinny thing (with a greater ZIndex) then just make the spinny thing visible as required.

This, however, is getting hard. Canvases do not seem well set up for this and I think I might be barking up the wrong tree.

I would appreciate any help. Thanks.

like image 602
dave Avatar asked Dec 22 '10 02:12

dave


2 Answers

I have done this with a few programs. Here it is in a nutshell:

(This is easiest with MVVM. It has been so long since I used the codebehid for things like this I can't really say if there is a good way to do it.)

  1. Create a border on your Main Window. I usually make it black with a 50% transparency. Add a grid to it, and put whatever you want inside to tell users it is busy. Size the border and the controls inside it to fill the screen.
  2. Create a property on your main ViewModel for IsBusy as boolean. Initialize it as False. Bind the Visibility property of the Busy Border to that property.
  3. Next, make a converter class for Busy(Boolean) to Visibility. Write the logic into that so that when value is True, Then visibility is Visible, when value is false, visibility is collapsed. ( http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx ).
  4. Back on the border, add your converter to the binding. Add code to the ViewModel for each of your Pages or Views that calls back to that property and sets it to true when your other thread is busy.

Cory

Edit:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">

<Grid>

    <Border BorderBrush="Black" BorderThickness="1" Background="#80000000" Visibility="Collapsed">
        <Grid>
            <TextBlock Margin="0" TextWrapping="Wrap" Text="Busy...Please Wait" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26.667" FontWeight="Bold" Foreground="#7EFFFFFF"/>
        </Grid>
    </Border>

    <DockPanel x:Name="LayoutRoot">
        <CheckBox Content="CheckBox" VerticalAlignment="Top"/>
        <TextBlock TextWrapping="Wrap"><Run Text="TextBlock"/></TextBlock>
        <UserControl x:Name="ViewViewView"/>
    </DockPanel>
</Grid>

like image 84
CodeWarrior Avatar answered Nov 08 '22 20:11

CodeWarrior


Look at this WPF toolkit with a busy indicator: https://github.com/xceedsoftware/wpftoolkit/wiki/BusyIndicator

like image 43
SeeSharp Avatar answered Nov 08 '22 20:11

SeeSharp