Omni-present progress bar

Sometimes you need a progress bar (or any other control) on potentially all pages in your windows phone application. In these cases, you can use the root frame template to specify the progress bar on your main XAML and give access to it through the application object. This way, your pages can share the same progress bar. It’s actually pretty simple to do. Three steps:

1. Define your template for the root frame.

2. Once loaded, get a ref to the progress bar

3. Extra credit: Create an “addref/release” mechanism for showing/hiding the progress bar.

Step 1: Template

Define your template resource – easiest way to do this is in the app’s resources:

<Application.Resources>

<ControlTemplate x:Key=”TopLevelTemplate” TargetType=”phone:PhoneApplicationFrame”>

<Grid x:Name=”GlobalContainer”>

<Grid Grid.Row=”0″ x:Name=”ClientArea” >

<ContentPresenter />

<ProgressBar IsIndeterminate=”True” HorizontalAlignment=”Stretch” VerticalAlignment=”Top” Loaded=”ProgressBar_Loaded” Visibility=”Collapsed”/>

</Grid>

</Grid>

</ControlTemplate>

</Application.Resources>

The <ContentPresenter> element is where the app will put your actual page. The <ProgressBar> element will create the shared progress bar control – in this case, we are placing it at the top of the page.

Next, in the code, make sure to assign the template to the root element:

public partial class App : Application

{

///

public App()

{

// …

RootFrame.Template = App.Current.Resources[“TopLevelTemplate”] as ControlTemplate;

}

This will guarantee that the template is properly assigned.

Step 2: Gain access to the progress bar

The App does not have the same designer facilities as a windows phone page does and so assigning a Name to the control does not create the backing field for it (as it would on a phone page). And so, you need to gain access to it. One way of doing it is to hook the Loaded event (see above in the XAML) and in it, place the control in a field:

public partial class App : Application

{

private ProgressBar m_progressBar;

private void ProgressBar_Loaded(object sender, RoutedEventArgs e)

{

m_progressBar = (ProgressBar)sender;

}

}

Now that we have access to the progress bar, all you need to do to show/hide it is to use ((App)Application.Current).ProgressBar to show/hide it as needed.

Step 3: Extra credit

Since there are going to be multiple pages interacting  with the control, it would be nice if it was self regulating (as to when to show and when to hide). A simple ref count mechanism can help here:And that’s about it – every time you do something that requires a progress bar, call ShowProgress(true). Otherwise, call ShowProgress(false).

public partial class App : Application

{

public void ShowProgress(bool show)

{

int d = show ? 1 : -1;

m_progressCount += d;

if (m_progressCount > 0)

{

m_progressBar.Visibility = Visibility.Visible;

}

else

{

m_progressBar.Visibility = Visibility.Collapsed;

}

}

}

Hope this helps.
http://cid-f5e0c616077a5eda.office.live.com/embedicon.aspx/BlogPublic/EverProgress.zip

About these ads
This entry was posted in Dev, Windows Phone and tagged , , , , . Bookmark the permalink.

4 Responses to Omni-present progress bar

  1. Vijai says:

    Thanks this code just works!!!

  2. Wolf Loescher says:

    Good post! I extended your ShowProgress method to also “dim” the content screen…

            public void ShowProgress(bool show)
            {
                // Update progress bar count
                int d = show ? 1 : -1;
                _progressBarCount += d;
                if (_progressBarCount  0)
                {
                    // Set root background
                    rootFrame.Background = new SolidColorBrush(Colors.White);
                    rootFrame.Opacity = 0.75;
                    
                    // Show progress bar
                    _progressBar.Visibility = Visibility.Visible;
                }
                else if (_progressBarCount == 0)
                {
                    // Set root background
                    rootFrame.Background = new SolidColorBrush(Colors.White);
                    rootFrame.Opacity = 1;
    
                    // Hide progress bar
                    _progressBar.Visibility = Visibility.Collapsed;
                }
            }
    
    • Wolf Loescher says:

      My code got munched…let’s try that again.

      public void ShowProgress(bool show)
      {
      // Update progress bar count
      int d = show ? 1 : -1;
      _progressBarCount += d;
      if (_progressBarCount 0)
      {
      // Set root background
      rootFrame.Background = new SolidColorBrush(Colors.White);
      rootFrame.Opacity = 0.75;

      // Show progress bar
      _progressBar.Visibility = Visibility.Visible;
      }
      else if (_progressBarCount == 0)
      {
      // Set root background
      rootFrame.Background = new SolidColorBrush(Colors.White);
      rootFrame.Opacity = 1;

      // Hide progress bar
      _progressBar.Visibility = Visibility.Collapsed;
      }
      }

  3. Wolf Loescher says:

    (Grrr….no preview, so I have no idea what the actual post will look like!)

    Good post!

    I extended your ShowProgress method to also “dim” the content screen. First we need to define the root frame…

    var rootFrame = ((App)Application.Current).RootFrame as PhoneApplicationFrame;

    And then set it’s opacity based on whether or not we are showing the progress bar…

    if (m_progressCount > 0) 
    {
         rootFrame.Opacity = 0.75;
    }
    else
    {
         rootFrame.Opacity = 1;
    }
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s