I quite like to have a global Performance Progress Bar in my Windows Phone 7 apps so the user has a consistent frame of reference when I’m interacting with web services. The requirements are simple, a progress bar that appears on all pages without any special requirements (ie. no custom controls, special code snippets, etc.). It should be managed in one place, and be easy to extend. Fortunately the extreme flexibility Silverlight offers makes this a doddle:
First add the following style to your App.xaml file:
<Style x:Key="mainFrameStyle" TargetType="phone:PhoneApplicationFrame"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="phone:PhoneApplicationFrame"> <Border x:Name="ClientArea" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"> <Grid> <toolkit:PerformanceProgressBar IsIndeterminate="True" VerticalAlignment="Top" Canvas.ZIndex="999" Foreground="{StaticResource PhoneAccentBrush}" Visibility="Collapsed" Loaded="globalProgressBar_Loaded" /> <layout:ContentControl ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}"> </layout:ContentControl> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
Next go into the code behind, and add the following variable to the top of the class:
private PerformanceProgressBar _globalProgressBar = null;
Next add the following methods to the bottom the App class:
private void globalProgressBar_Loaded(object sender, RoutedEventArgs e) { _globalProgressBar = sender as PerformanceProgressBar; } public void ShowProgressBar() { if (_globalProgressBar != null) _globalProgressBar.Visibility = Visibility.Visible; } public void HideProgressBar() { if (_globalProgressBar != null) _globalProgressBar.Visibility = Visibility.Collapsed; }
Now find the InitializePhoneApplication() method, and amend the RootFrame instantiation code to the following:
RootFrame = new PhoneApplicationFrame() { Style = (Style)Resources["mainFrameStyle"] };
And you’re done! You can call the progress bar like so:
((App)App.Current).ShowProgressBar();
((App)App.Current).HideProgressBar();
You can download the sample project here for your reference.
Update: This method for displaying a global ProgressBar doesn’t always play well with the WP7 Toolkit Transitions. However, I would highly recommend using the WP7Contrib Transitions anyway (they work well with the global ProgressBar too). I’ve created a 3-part guide on the transitions here.