Friday, April 19, 2013

Custom WPF Progress Bars - Part I

One of the biggest advantages of Windows Presentation Foundation Technology of Microsoft is the freedom that the developer must create or modify existing components. This is possible because all traditional components (TextBox, CheckBox, ComboBox, Menu, ProgressBar, TreeView, etc.) are mounted literally like lego bricks, the From the most basic components. These basic components are implemented the System.Windows.Controls assembly and, among the main are: Grid, StackPanel, DockPanel, Border, Canvas and Image. The use of these elements together with elements present in other assemblies that help developer to implement geometric designs (Rectangle, Circle) and basic interactions (MouseOver, Click, etc) allow you to create, basically component you want.
The ProgressBar component of WPF is no different. It is formed by three graphic elements, whose names are well defined:
·         PART_Indicator: component part which indicates the progress indeed.
·         PART_Track: indicates the trail or path that is traversed by indicator (PART_Indicator).
·         PART_GlowRect: this is only a component to help with visual effects.
The purpose of this post is to show how these three elements can be created and attached to existing code ProgressBar component to generate a progress bar that looks arbitrary.

The Figure 1 shows a window created in WPF, which displays the lower left corner of the progress bar one whose appearance had been totally customized for the application in question. The black part is formed by a rectangle with Name property equal to "PART_Indicator" and represents the indicator, as shown in the following code snippet:
<Rectangle Name="PART_Indicator" HorizontalAlignment="Left" Margin="2" Fill="Black"/>
Figure 1 – progress bar to be assembled.
The edge of the progress bar, together with its interior White metallic, shape the way that the indicator should go and therefore Name property is equal to "PART_Indicator". With these two defined components (PART_Track and PART_Indicator), it is possible to have a progress bar fully functional. However, to merge both components, it was decided to use a Grid and declare PART_Track and PART_Indicator so that the indicator always appear superimposed over the track (PART_Track), as shown in the code below:
<Grid Name="PART_Track">

       <Rectangle HorizontalAlignment="Stretch" Fill="{StaticResource ResourceKey=BackgroundDegrade}"/>
       <Rectangle Name="PART_Indicator" HorizontalAlignment="Left" Margin="2" Fill="Black"/>
The next step is adding the text displayed in the progress track. That Functionality is not trivial, that is, it is not something already present in the WPF ProgressBar default. Therefore, some "club" is needed for work properly.
Firstly, it is necessary to position the component TextBlock centered and superimposed on the indicator (PART_Indicator). To do this, simply declare it within the tag <Grid>:
<Grid Name="PART_Track">

       <Rectangle HorizontalAlignment="Stretch" Fill="{StaticResource ResourceKey=BackgroundDegrade}"/>
       <Rectangle Name="PART_Indicator" HorizontalAlignment="Left" Margin="2" Fill="Black"/>

             <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type ProgressBar}}, Path=Value, StringFormat={}{0:0.#}%}" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center"/>
Particular attention must be given to that TextBlock this moment. Firstly, it is worth noting the Binding used in the Text property. This binding is responsible for connecting the text to progress bar progress (ProgressBar Value property). As we are assuming that the property Value ranges from 0 to 100, then its value is exactly the percentage of progress to be displayed. Note that for the binding to work, you must define a data source, which in this case is the very instance of the ProgressBar. That's why we used the attribute RelativeSource. The next figure shows how is the progress bar up to now.
Figure 2 – part I progress bar.
At this point, we have a progress bar completely functional and able to show her progress as a percentage. on However, some issues are still open:
1.       What happens when the progress indicator goes under the text Progress?
2.       How can you give a more dynamic look to the progress bar?
3.       How about the Indeterminate progress bar?
4.       How to make different types of progress bar? (circular, vertical, ...).
The next post will address each of the items put into question. In particular, the first item is of special importance because it is a bug interface in the current code, the text of progress disappears because it is the same color indicator that the bottom (black). The solution is to change the color of text progress to white when the indicator reaches the letter. To resolve this, will need an additional TextBlock, the text color is white, superimposed TextBlock text to black (the existing code). For the TextBlock white only appears when the background is black, we will make use of Clip property of the TextBlock, which will be explained in the next post.
Dear developers, I hope you enjoyed. If so, please click the like button to help us spreading out! If you have any questions and comments, please post. The code to see the bar progress of this post is in action at the link below:


Anonymous said...

Great post. Is it possible to write something on next post about a metro like indeterminate progressbar?

TapiocaCom Código said...

Sure. I will try to make some comments on that. Best regards.

Anonymous said...

C# create custom progress bar for .NET application

Post a Comment