How to Create a Silverlight ProgressBar Like the 1C Enterprise 8.2 Progress Bar
Written by Andrew Ivanov Monday, 26 March 2012
My attention was recently drawn to the splash screen of 1C Enterprise 8.2. Namely, I liked the elegant progress bar. See picture below:

So without thinking twice, I decided that it would be nice to add the stylish progress bar to my arsenal of Silverlight controls. Here’s how:
I started by creating a new templated control with the next template:
Generic.xaml<Style TargetType=”local:ProgressBar1C”>
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”local:ProgressBar1C”>
<Grid>
<ItemsControl x:Name=”itemsControl”
HorizontalAlignment=”Center”
VerticalAlignment=”Center”>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation=”Horizontal” />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then I created another templated control to present one section of the progress bar. This conrol contains two visual states – filled and unfilled.
![]()
<Style TargetType=”local:ProgressBarItem1C”>
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”local:ProgressBarItem1C”>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name=”FilledGroup”>
<VisualState x:Name=”Unfilled” />
<VisualState x:Name=”Filled”>
<Storyboard>
<ColorAnimation Duration=”0″
Storyboard.TargetName=”filledGrid”
Storyboard.TargetProperty=”(Background).(SolidColorBrush.Color)”
To=”#B5B5B5″ />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background=”White”
BorderBrush=”#7F7F7F”
BorderThickness=”1″
CornerRadius=”3″
Margin=”2, 0, 2, 0″
Padding=”1″
Width=”36″
Height=”10″>
<Grid x:Name=”filledGrid” Background=”White” />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ProgressBarItem1C.cspublic class ProgressBarItem1C : Control
{
public static readonly DependencyProperty IsFilledProperty = DependencyProperty.Register(“IsFilled”, typeof(bool), typeof(ProgressBarItem1C), new PropertyMetadata(false, new PropertyChangedCallback(IsFilledPropertyChangedCallback)));
public bool IsFilled
{
get { return (bool)this.GetValue(IsFilledProperty); }
set { this.SetValue(IsFilledProperty, value); }
}
public ProgressBarItem1C()
{
this.DefaultStyleKey = typeof(ProgressBarItem1C);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
UpdateVisualState();
}
private void UpdateVisualState()
{
VisualStateManager.GoToState(this, (IsFilled) ? “Filled” : “Unfilled”, false);
}
private static void IsFilledPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ProgressBarItem1C sender = (ProgressBarItem1C)d;
sender.UpdateVisualState();
}
}
ProgressBar1C.cs
[TemplatePart(Name = "itemsControl", Type = typeof(ItemsControl))]
public class ProgressBar1C : Control
{
#region Const
private const int ITEMS_COUNT = 10;
public const int ProgressMinValue = 0;
public const int ProgressMaxValue = 10;
#endregion
private ProgressBarItem1C[] items;
private ItemsControl itemsControl;
public static readonly DependencyProperty ProgressValueProperty = DependencyProperty.Register(“ProgressValue”, typeof(int), typeof(ProgressBar1C), new PropertyMetadata(0, new PropertyChangedCallback(ProgressValuePropertyChangedCallback)));
public int ProgressValue
{
get { return (int)this.GetValue(ProgressValueProperty); }
set { this.SetValue(ProgressValueProperty, value); }
}
public ProgressBar1C()
{
this.DefaultStyleKey = typeof(ProgressBar1C);
CreateItems();
}
public override void OnApplyTemplate()
{
ClearItemsControl();
base.OnApplyTemplate();
itemsControl = GetTemplateChild(“itemsControl”) as ItemsControl;
FillItemsControl();
UpdateState();
}
private void CreateItems()
{
items = new ProgressBarItem1C[ITEMS_COUNT];
for (int i = 0; i < ITEMS_COUNT; i++)
{
items[i] = new ProgressBarItem1C();
}
}
private void ClearItemsControl()
{
if (itemsControl != null)
{
itemsControl.Items.Clear();
}
}
private void FillItemsControl()
{
if (itemsControl != null)
{
itemsControl.ItemsSource = items;
}
}
private void UpdateState()
{
int progressValue = ProgressValue;
if (progressValue < ProgressMinValue)
{
progressValue = ProgressMinValue;
}
else if (progressValue > ProgressMaxValue)
{
progressValue = ProgressMaxValue;
}
items.Skip(progressValue).Take(ITEMS_COUNT – progressValue).ToList().ForEach((item) => item.IsFilled = false);
items.Take(progressValue).ToList().ForEach((item) => item.IsFilled = true);
}
private static void ProgressValuePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ProgressBar1C sender = (ProgressBar1C)d;
sender.UpdateState();
}
}
As you can see, in no more than an hour, we have a simple and beautiful progress bar!
Looking for quality Silverlight Hosting? Look no further than Arvixe Web Hosting!
Tags: bar, how to, manager, progress, ProgressBar, Silverlight, state, Storyboard, visual, VisualState, VisualStateManager
