5

Progress bar style in WPF is old fashioned. Increments in Bars. How to implement a progress bar with vista or windows-7 shady glow effect ?

Image http://quickshare.my3gb.com/download/2.JPG

Even checked out the properties of the Progressbar. But, there is no properties related to glowy effect.

Also, is there any animations or something different from normal progress bar/

Edit

The Code:

<ProgressBar Height="41" HorizontalAlignment="Left"    Margin="372,215,0,0" Name="progressBar1" VerticalAlignment="Top" Width="150">
            
</ProgressBar>
GEOCHET
  • 21,119
  • 15
  • 74
  • 98
  • 1
    I think you need to be using the Aero theme in Windows 7 (Windows 7 Basic or Windows 7) to get the smooth glowing increments. If you switch to Windows Classic then you get the bars. If you for some reason want to have a smooth progress bar themed even when in non-Aero, then you could copy the Progress Bar Template that defines the "look" when in Aero. – Colin Smith Aug 15 '12 at 10:52
  • I tried changing styles (themes) and even tried Win 8 too! The app still shows the traditional bars – now he who must not be named. Aug 15 '12 at 10:55
  • It won't be quite the same look...but you might be able to use something from the BusyIndicator in the ExtendedWPFToolkit ... http://wpftoolkit.codeplex.com/wikipage?title=BusyIndicator&referringTitle=Home – Colin Smith Aug 15 '12 at 10:59
  • Your Progress Bar "should" use Aero...which OS are you running on ? Could you show the XAML for your ProgressBar...are you styling it in any way. .....To Force your WPF application to use Aero, then you could do this.... http://arbel.net/2006/11/03/forcing-wpf-to-use-a-specific-windows-theme/ ... and here.... http://www.kennethham.com/wp/2010/11/force-wpf-to-use-windows-7aero-theming-in-classic-mode/ – Colin Smith Aug 15 '12 at 11:02
  • To be honest, my progress bar is shiny in WPF....why isn't yours? What OS are you running? – Charleh Aug 15 '12 at 11:03
  • Charleh, I am using both Win xp Sp3 and Win 8 for development. checked out both. No luck with glow effect >( What 0S are u using! By the way, I use Microsoft Visual Studio 2010 (Premium version) ! – now he who must not be named. Aug 15 '12 at 11:12
  • The Glow effect has been taken out of Windows 8...they are ditching most of the Aero chrome. As for Windows XP SP3, that doesn't have Aero....use one of the links I showed you above to Force WPF to use it's own Aero themeing no matter what OS you are on. – Colin Smith Aug 15 '12 at 11:18
  • Thanks Colinsmith. May be i would try executing the same app in Win 7 and then post whats happening there! – now he who must not be named. Aug 15 '12 at 11:29
  • I've added a quick example on how to grow your own, in case you want to go that route. – Charleh Aug 15 '12 at 11:31
  • [Duplicate] (http://stackoverflow.com/questions/4815175/wpf-progressbar-style) – Bob Vale Aug 15 '12 at 11:59
  • Does this answer your question? [WPF progressbar style is blocky?](https://stackoverflow.com/questions/4815175/wpf-progressbar-style-is-blocky) – StayOnTarget Jul 13 '21 at 20:23

4 Answers4

11

Roll your own shouldn't be too hard.

Create a usercontrol which has the properties of a standard progress bar

Value
Maximum
Minimum

You can create a derived property which calculates the size of the bar by using the a formula:

ProgressBarWidth = (Value / (Maximum + Minimum) * ControlWidth) - Padding

Which changes when the Value, Maximum or Minimum is updated

Bind this to the Width of the 'bar' in your progress bar control template - this way when the Value property is updated, the progress bar will resize.

How your bar looks is up to you, but I guess you just want a load of fancy fills/gradients/glow effects - you can add these in Blend

Disclaimer: Formulas may be incorrect!

In case you want to try and roll your own, here's one I just knocked up which seems to work ok

public partial class MyProgressBar : UserControl
    {
        public MyProgressBar()
        {
            InitializeComponent();

            Loaded += new RoutedEventHandler(MyProgressBar_Loaded);
        }

        void MyProgressBar_Loaded(object sender, RoutedEventArgs e)
        {
            Update();
        }

        private static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(MyProgressBar), new PropertyMetadata(100d, OnMaximumChanged));
        public double Maximum
        {
            get { return (double)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }


        private static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(MyProgressBar), new PropertyMetadata(0d, OnMinimumChanged));
        public double Minimum
        {
            get { return (double)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }

        private static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(MyProgressBar), new PropertyMetadata(50d, OnValueChanged));
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }



        private static readonly DependencyProperty ProgressBarWidthProperty = DependencyProperty.Register("ProgressBarWidth", typeof(double), typeof(MyProgressBar), null);
        private double ProgressBarWidth
        {
            get { return (double)GetValue(ProgressBarWidthProperty); }
            set { SetValue(ProgressBarWidthProperty, value); }
        }

        static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            (o as MyProgressBar).Update();
        }

        static void OnMinimumChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            (o as MyProgressBar).Update();
        }

        static void OnMaximumChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            (o as MyProgressBar).Update();
        }


        void Update()
        {
            // The -2 is for the borders - there are probably better ways of doing this since you
            // may want your template to have variable bits like border width etc which you'd use
            // TemplateBinding for
            ProgressBarWidth = Math.Min((Value / (Maximum + Minimum) * this.ActualWidth) - 2, this.ActualWidth - 2);


        }          
    }

The XAML

<UserControl x:Class="WpfApplication1.MyProgressBar"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" x:Name="uc">
    <Grid>
        <Border Background="White">
            <Border BorderBrush="Gray" BorderThickness="1">
                <Grid>
                    <Grid.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FFE5E5E5" Offset="0" />
                            <GradientStop Color="White" Offset="1" />
                        </LinearGradientBrush>
                    </Grid.Background>
                    <Grid Width="{Binding ProgressBarWidth, ElementName=uc}" HorizontalAlignment="Left">
                        <Grid.Background>
                            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                                <GradientStop Color="#FFCBFFD0" Offset="0" />
                                <GradientStop Color="#FF62EF73" Offset="1" />
                                <GradientStop Color="#FFAEE56D" Offset="0.39" />
                            </LinearGradientBrush>
                        </Grid.Background>
                    </Grid>
                </Grid>
            </Border>
        </Border>
    </Grid>
</UserControl>

The result:

Progress bar... home grown!

Like I said, something like this is pretty easy but still consider redefining the template or using the original since it does support glowyness on the right OS

Here it is after I added a 'Percent' dependency property and bound to that in the control template:

Home grown with number!

Code for updating Percent was

   Percentage = Math.Min((int)(Value / (Maximum + Minimum) * 100), 100);

Edit 2:

I messed with the fills and added a white inner border so it looks more shiny. The only thing missing is the shiny animation

the top one is my control, the bottom one is the default WPF one

Bear in mind, all of this may be possible just by editing the progress bar control template

Oooh shiny...

Here's the updated XAML:

<UserControl x:Class="WpfApplication1.MyProgressBar"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" x:Name="uc">
    <Grid>
        <Border Background="White" BorderBrush="Gray" BorderThickness="1">
            <Border BorderBrush="White" BorderThickness="1">
                <Grid>
                    <Grid.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FFE5E5E5" Offset="0" />
                            <GradientStop Color="White" Offset="1" />
                        </LinearGradientBrush>
                    </Grid.Background>
                    <Grid Width="{Binding ProgressBarWidth, ElementName=uc, FallbackValue=200}" HorizontalAlignment="Left">
                        <Grid.Background>
                            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                                <GradientStop Color="#FF8BBA91" Offset="0" />
                                <GradientStop Color="#FF8BBA91" Offset="1" />
                                <GradientStop Color="#FF9ED76A" Offset="0.8" />
                                <GradientStop Color="#FF9ED76A" Offset="0.2" />
                            </LinearGradientBrush>
                        </Grid.Background>
                    </Grid>
                    <Border>
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#89E2E2E2" Offset="0" />
                                <GradientStop Color="#C1FFFFFF" Offset="0.5" />
                                <GradientStop Color="Transparent" Offset="0.52" />
                            </LinearGradientBrush>
                        </Border.Background>
                    </Border>
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Percentage, ElementName=uc}"></TextBlock>
                </Grid>
            </Border>
        </Border>
    </Grid>
</UserControl>
Charleh
  • 13,749
  • 3
  • 37
  • 57
  • Thanks Charleh ! I shall try out Blend. Yes, I need some fancy stuff like a .gif image with percentage shown in the middle. Guess, it should be possible with Blend! – now he who must not be named. Aug 15 '12 at 10:57
  • Like Vincent said you could always redefine the control template - it might be better if you don't need additional functionality that isn't achieved by binding (I think a percentage indicator could work using binding, I'll give it a try) – Charleh Aug 15 '12 at 11:02
  • Testing out the codes Charleh. Is it like adding new files (the XAML and the class you gave to the project right ? I am checking out..) – now he who must not be named. Aug 15 '12 at 11:32
  • Yeah just add a new UserControl to the project and copy/paste the XAML. Make sure you rename the `x:Class` in the XAML to the same namespace/class as your new usercontrol. You will also need to change the `DependencyProperty.Register` calls so that `typeof(MyProgressBar)` uses your uc type name. Either that or you can just copy/paste the whole lot into a new UC - it will rename the class to MyProgressBar so it might not match the filename... then you just need to add the namespace and add the control – Charleh Aug 15 '12 at 11:38
  • Any reason you are not just restyling the existing control rather than creating a new control – Bob Vale Aug 15 '12 at 11:56
  • Nope - like I said, no reason that the old one couldn't do this when a control template change is done. I was just showing that this is pretty simple to do if a home-grown control is required which had additional functionality over the original (such as a percentage text - which I've also said may be possible just using bindings on the original control template). Just a bit of fun too :) – Charleh Aug 15 '12 at 12:01
  • That was great Charleh.. It now works! for a newbie like me, this taught me about home made custom controls and how to use one like this. Thanks for quick reply and great examples. I had included an xaml file and a .cs file with user control and renamed it. Works fine. – now he who must not be named. Aug 15 '12 at 12:12
  • Cool, glad it helped - I'd also definitely look at ControlTemplates and control parts - these are separate from styles (but can be applied by styles) and allow you to completely redefine any controls look and feel without changing any code (or even needing the code since you can change the control template of any out-of-box WPF control). This is one of my favourite aspects of WPF: info here: http://dotnet.dzone.com/articles/control-templates-wpf – Charleh Aug 15 '12 at 13:05
5

You need to be using the Aero theme (i.e. Windows 7 Basic, or Windows 7) in your Personalization settings of Windows in order to get the smooth progress bar and animated glow look.

Vista and Windows 7 have the Aero theme. It didn't even exist when Windows XP was released. It was also removed in Windows 8 for a more standard look across the board. If you switch to Windows Classic then you get the old chunky bars look for the progress bar.

WPF has a different set of Templates defined for Luna, Aero, Royale, Classic.....what it does is look at the theme your system is currently using, and then this makes it decide which set of WPF Templates to use.

So when you are on XP, it never gets the opportunity to use the Aero set of templates.

If for some reason you want to have your progress bar themed with the Aero look even when Windows is not using the Aero theme then there are 2 main solutions.

The solutions:

You can force your WPF application to use the Aero-themed WPF templates for all of its controls:

OR

If you don't want all of your applications controls to be themed as Aero, then just take the style/template that defines the Aero look of the ProgressBar from the Aero theme resources and apply it to your ProgressBar.

Hopefully either way will get you your glowing progress bar....note, I don't have XP to test if this is the case.

Community
  • 1
  • 1
Colin Smith
  • 12,375
  • 4
  • 39
  • 47
1

You can mimic the animation using the following, which is a tweak for the accepted answer:

<Grid Background="LightGray">
    <Grid Width="{Binding ProgressBarWidth, ElementName=uc}" HorizontalAlignment="Left">
        <Grid.Triggers>
            <EventTrigger RoutedEvent="Rectangle.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Background.(GradientBrush.GradientStops)[1].(GradientStop.Offset)" From="-1" To="0" Duration="0:0:1.5" RepeatBehavior="Forever"/>
                        <DoubleAnimation Storyboard.TargetProperty="Background.(GradientBrush.GradientStops)[2].(GradientStop.Offset)" From="0" To="1" Duration="0:0:1.5" RepeatBehavior="Forever"/>
                        <DoubleAnimation Storyboard.TargetProperty="Background.(GradientBrush.GradientStops)[3].(GradientStop.Offset)" From="1" To="2" Duration="0:0:1.5" RepeatBehavior="Forever"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Grid.Triggers>
        <Grid.Background>
            <LinearGradientBrush>
                <GradientStop Color="#FF218ED6" Offset="0.0" />
                <GradientStop Color="#FF4BA5E0" Offset="0.4" />
                <GradientStop Color="#FF8ECCF5" Offset="0.5" />
                <GradientStop Color="#FF4BA5E0" Offset="0.6" />
                <GradientStop Color="#FF218ED6" Offset="1.0" />
            </LinearGradientBrush>
        </Grid.Background>
    </Grid>
</Grid>

Preview:

enter image description here

0

If you want to change the look of the Progress Bar, you'll have to re-define its (Control)Template.
ms explains this here :
http://msdn.microsoft.com/en-us/library/ms750638.aspx
When writing the Template, to get the glow, You can use the BitmapEffect, with a OuterGlowBitmapEffect (!Software rendered), but Best is to use Effect (more up to date).

Maybe you don't have to redefine the Template if you use the Effect of the progress bar and it suits you.

Notice that you have good free themes for your application on the net.

GameAlchemist
  • 18,995
  • 7
  • 36
  • 59
  • Thanks Vincent! Being a newbie to WPF,this is informative. And yes, I checked out the Effect property. (I clicked the progress bar, go to properties, searched "Effect"). It just displayed "Value must be set through XAML. How do one do that in XAML ? something like .This didn workout anyway.But, what should we specify for Effect then in XAML ? – now he who must not be named. Aug 15 '12 at 11:09
  • Wpf has two means to give a property a value, use the second syntax, which in your case is : – GameAlchemist Aug 15 '12 at 11:18
  • Vincent Piel, with your code the progress bar is reasonably good.Thanks for that. But still no glow effect! ? – now he who must not be named. Aug 15 '12 at 11:31
  • maybe try the deprecated OuterGlowBitmapEffect ... I don't know i never did glow. Dig for that particular point (how to do a Glow in general) on the net. – GameAlchemist Aug 15 '12 at 11:42