Silverlight 2 provides an attractive platform for creating Rich Internet Applications, however when first getting started both the oddities of the layout model and the strange absence of certain controls and class and be puzzling.
One such puzzling absence from the Silverlight tool chest is a progress bar control. WPF has a progress bar, WinForms has a progress bar, but not Silverlight. Fortunately implementing one is not that hard and provided a great introduction to Silverlight’s layout model.
Silverlight and layers
Unlike ASP.NET, and many other forms technologies, Silverlight uses a multiple layer positioning system. The Canvas control is especially useful for allowing multiple controls to be layered.
Take for example this simple block of XAML:
<Canvas x:Name="LayoutRoot" Background="WhiteSmoke"> <Rectangle Width="60" Height="60" Fill="Green" /> <Rectangle Width="60" Height="60" Fill="Gray" /> <Rectangle Width="60" Height="60" Fill="LightBlue" /> </Canvas>
To the human reading the XAML we see 3 rectangles of different colors.
However, when rendered the viewer of the Silverlight application will only see the blue rectangle.
This is because in Silverlight the multiple layers are merged together before rendering. This feature allows for some pretty stunning effects using transparences.
Back to the Progress Bar
The layering abilities of Silverlight also permit a simple progress bar to be accomplished using only two Rectangles. The idea is to have a outer rectangle outlined in black but transparently filled to represent the border of the progress bar. The other rectangle would then be positioned below the previously mentioned rectangle. This one would be solidly filled with blue to represent the current progress. It is this second rectangle that would be resized to representing the changing in progress.
The first step is to actually create the Rectangle controls to represent the two previously mentioned.
<Canvas x:Name="LayoutRoot" Background="WhiteSmoke"> <Rectangle x:Name="rcProgress" Width="60" Height="20" Fill="Blue" /> <Rectangle x:Name="rcBorder" Width="160" Height="20" Stroke="Black" Fill="Transparent" /> </Canvas>
The Rectangle named rcBorder is intentionally declared last so that it would occupy the top most layer in the Silverlight rendering engine. To prevent the rcBorder rectangle from completely blocking the rcProgress rectangle, the Fill is set to transparent to prevent all but the border of rcBorder from being seen.
Now, with all the controls in place all the is left is to add the little bit of C# needed to resize rcProgress. For that we can create a method call SetProgress that accepts a Double representing the percent (1.0 to 100.0) value that the progress bar need to present.
private void SetProgress(double percent) { rcProgress.Width = rcBorder.Width*(percent/100.0); }
That is about as simple as it gets for a basic progress bar. For those interested, I have also created a working demonstration in the form of a Visual Studio 2008 solution that can be downloaded from here.