(7 votes)

The ProgressBar control in Silverlight 2

4 comments   /   posted by Martin Mihaylov on Oct 07, 2008

With the release of the Release Candidate version of Silverlight 2 three long awaited controls were presented - the PasswordTextBox, the ComboBox and the ProgressBar. Since the need of such controls were pretty big, a lot of custom controls were created and the existing ones have been extended in order to fill that need. Probably you've already read a couple of tutorials about creating your own ProgressBar control. We have also developed our own simple progress bar for the Voting control and I was ready to show it off in a separate article, but that's not necessary now. Instead of this we are going to take a look at the ProgressBar control that came with the release candidate and show some of its basic features.

Download source code

Declaring a ProgressBar control

The ProgressBar control is located in the System.Windows.Controls.dll and we can add it to our application either by dragging it form the Toolbox in the Xaml or declaring it in the codebehind:

Xaml

<Grid x:Name="LayoutRoot" Background="White">
    <ProgressBar x:Name="MyProgressBar" Width="400" Height="30"></ProgressBar>
</Grid>

C#

ProgressBar MyProgressBar = new ProgressBar();
MyProgressBar.Width = 400;
MyProgressBar.Height = 30;
 
LayoutRoot.Children.Add( MyProgressBar );

If you now view your application in the browser you'll see an empty progress bar, so in the next step let's add some action to it. For that purpose we have to options.

Determinate and indeterminate progress bar

The progress bar has two states - determinate and indeterminate - and to choose between them we use the IsIndeterminate property of the control.

Determinate

When set to false, the ProgressBar control reports progress based on the Value property. In this case we have to set the Minimum and Maximum properties too:

<Grid x:Name="LayoutRoot" Background="White">
    <ProgressBar x:Name="MyProgressBar" IsIndeterminate="False" Minimum="0" Maximum="100" Value="30" 
                 Width="400" Height="30"></ProgressBar>
</Grid>

The progress is calculated on the base of the range (Maximum - Minimum) and the Value property. To change the progress we have to change the Value property. Here is a little sample: 

For example we can use this in a scenario where we're downloading a file and the overall length of the process is known.

Indeterminate

When the IsIndeterminate property is set to true, the ProgressBar control reports generic progress with a repeating pattern, like this:

In this case the progress doesn't depend on the Value property so we don't have to set anything else.

The indeterminate progress bar can be used in scenario where the process with unknown length is in progress, like calling a web service for example.

Styling

We can style the ProgressBar control as any other Silverlight control and here are some examples for basic changes in the look of the control.

Background and Foreground

The Background property is applied to the color of the container of the progress bar control and the Foreground property applies to the color of the progress bar.

<Grid x:Name="LayoutRoot" Background="White">
    <ProgressBar x:Name="MyProgressBar" IsIndeterminate="False" Background="Black" Foreground="Orange" 
                 Minimum="0" Maximum="100" Value="30" Width="400" Height="30"></ProgressBar>
</Grid>

Border

The ProgressBar control has a BorderBrush and a BorderThickness properties, which allow you to add a border to the control.

<Grid x:Name="LayoutRoot" Background="White">
    <ProgressBar x:Name="MyProgressBar" IsIndeterminate="False" BorderBrush="Black" BorderThickness="2" 
                 Background="Black" Foreground="Orange" Minimum="0" Maximum="100" Value="30" 
                 Width="400" Height="30">
    </ProgressBar>
</Grid>

Templating

The ProgressBar control allows templating and it can be done the standard way:

<ProgressBar x:Name="MyProgressBar" IsIndeterminate="False" Minimum="0" Maximum="100" Value="30" Width="400" Height="30">
    <ProgressBar.Template>
        <ControlTemplate>
            ...
        </ControlTemplate>
    </ProgressBar.Template>
</ProgressBar>

Important events

  • Value changed - raised when the Value property is changed.

Summary

This article was an overview of the basic features of the ProgressBar control. We have explained the two states of the progress bar, which make the control usable in different scenarios, and we have also showed how to make some basic changes to the look of the control. As a conclusion I can say that the Silverlight team did a really good job creating this control.

If you have any questions or suggestions, post them as comments and I will gladly answer you.



Comments

Comments RSS RSS
  • RE: The ProgressBar control in Silverlight 2  

    posted by Madu Alikor on Nov 28, 2008 12:37

    Can I have a Full Example of how to create a Silverlight ControlTemplate for the ProgressBar Control

  • RE: The ProgressBar control in Silverlight 2  

    posted by Steve on Dec 17, 2008 08:53

    please get me the full example

  • RE: The ProgressBar control in Silverlight 2  

    posted by Enrai on Dec 20, 2008 06:30

    Here is the default style for the ProgressBar control and in it you can find the ControlTemplate:

    <Style TargetType="ProgressBar">
        <Setter Property="Foreground" Value="#FF027DB8"/>
        <Setter Property="Background" Value="#FFD2D5D8" />
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Maximum" Value="100" />
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="BorderBrush">
            <Setter.Value>
                <LinearGradientBrush EndPoint=".5,1" StartPoint=".5,0">
                    <GradientStop Color="#FFAEB7BF" Offset="0"/>
                    <GradientStop Color="#FF919EA7" Offset="0.35"/>
                    <GradientStop Color="#FF7A8A99" Offset="0.35"/>
                    <GradientStop Color="#FF647480" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ProgressBar">
                    <Grid x:Name="Root">
                        <vsm:VisualStateManager.VisualStateGroups>
                            <vsm:VisualStateGroup x:Name="CommonStates">
                                <vsm:VisualState x:Name="Determinate"/>
                                <vsm:VisualState x:Name="Indeterminate">
                                    <Storyboard RepeatBehavior="Forever">
                                        <DoubleAnimation Storyboard.TargetName="IndeterminateGradientFill"
                                                     Storyboard.TargetProperty="(Shape.Fill).(LinearGradientBrush.Transform).(TransformGroup.Children)[0].X"
                                                     Duration="00:00:.5" From="0" To="20" />
                                        <ObjectAnimationUsingKeyFrames Duration="00:00:00" Storyboard.TargetName="IndeterminateRoot" Storyboard.TargetProperty="(UIElement.Visibility)">
                                            <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Duration="00:00:00" Storyboard.TargetName="DeterminateRoot" Storyboard.TargetProperty="(UIElement.Visibility)">
                                            <DiscreteObjectKeyFrame KeyTime="00:00:00">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                        </vsm:VisualStateManager.VisualStateGroups>
                        <!--Default Root Visuals for either type of ProgressBar-->
                        <Border Name="ProgressBarTrack" CornerRadius="3" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" />
                        <Grid x:Name="ProgressBarRootGrid" >
                            <!-- Beginning of Gradient over all visuals -->
                            <Rectangle Canvas.ZIndex="1" x:Name="ProgressBarRootGradient" StrokeThickness="1" Margin="{TemplateBinding BorderThickness}" Stroke="#FFFFFFFF" RadiusX="1.5" RadiusY="1.5">
                                <Rectangle.Fill>
                                    <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                                        <GradientStop Color="#B2FFFFFF" Offset="0" />
                                        <GradientStop Color="#C6FFFFFF" Offset="0.15"/>
                                        <GradientStop Color="#D1FFFFFF" Offset="0.275" />
                                        <GradientStop Color="#C6FFFFFF" Offset="0.4"/>
                                        <GradientStop Color="#BFFFFFFF" Offset="0.65" />
                                        <GradientStop Color="#A5FFFFFF" Offset="0.75"/>
                                        <GradientStop Color="#91FFFFFF" Offset="0.85"/>
                                        <GradientStop Color="#72FFFFFF" Offset="1" />
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                            <!-- Beginning of Indeterminate Progress Bar Visuals-->
                            <Grid x:Name="IndeterminateRoot" Visibility="Collapsed">
                                <Rectangle x:Name="IndeterminateSolidFill" Stroke="#FF448DCA" RadiusX="2" RadiusY="2" StrokeThickness="0" Margin="{TemplateBinding BorderThickness}" Fill="{TemplateBinding Foreground}" Opacity="1" RenderTransformOrigin="0.5,0.5" />
                                <Rectangle x:Name="IndeterminateGradientFill" RadiusX="2" RadiusY="2" StrokeThickness="1" Margin="{TemplateBinding BorderThickness}" Opacity="0.7" >
                                    <Rectangle.Fill>
                                        <LinearGradientBrush SpreadMethod="Repeat" MappingMode="Absolute" EndPoint="0,1" StartPoint="20,1">
                                            <LinearGradientBrush.Transform >
                                                <TransformGroup>
                                                    <TranslateTransform X="0" />
                                                    <SkewTransform AngleX="-30" />
                                                </TransformGroup>
                                            </LinearGradientBrush.Transform>
                                            <GradientStop Color="#FFFFFFFF" Offset="0"/>
                                            <GradientStop Color="#00FFFFFF" Offset=".25"/>
                                            <GradientStop Color="#FFFFFFFF" Offset="0.85"/>
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Grid>
                            <!-- Beginning of Determinate Progress Bar Visuals-->
                            <Grid x:Name="DeterminateRoot" Margin="1" >
                                <!--Background -->
                                <Rectangle HorizontalAlignment="Left" x:Name="ProgressBarIndicator" Margin="{TemplateBinding BorderThickness}" StrokeThickness="0.5" RadiusX="1.5" RadiusY="1.5" Fill="{TemplateBinding Foreground}"/>
                            </Grid>
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    Be careful when changing the content of the template as some of the elements are used by the ViewStates. If you need change them be sure to replace them with appropriate elements or adjust the ViseStates to work with the new ones.

  • RE: The ProgressBar control in Silverlight 2  

    posted by Vinay on Dec 24, 2008 14:41

    I want my Progress bar to appear on a button click which loads data from the database and shows in a datagrid and Progress bar should stop when Data loading is completed.

    thanks in advance.

Add Comment