How to Create a Silverlight ProgressBar Like the 1C Enterprise 8.2 Progress Bar

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.

 
Generic.xaml
 
    <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.cs
 
    public 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!

Demo

Source Code

Looking for quality Silverlight Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , , , | Posted under 3rd Party Software, Programming/Coding | RSS 2.0

Leave a Reply

Your email address will not be published. Required fields are marked *


× 3 = 15

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>