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!