Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

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>
like image 916
now he who must not be named. Avatar asked Aug 15 '12 10:08

now he who must not be named.


2 Answers

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>
like image 168
Charleh Avatar answered Sep 22 '22 19:09

Charleh


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:

  • http://arbel.net/2006/11/03/forcing-wpf-to-use-a-specific-windows-theme/

  • http://www.kennethham.com/wp/2010/11/force-wpf-to-use-windows-7aero-theming-in-classic-mode/

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.

  • Where can I download Microsoft's standard WPF themes from?

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

like image 23
CSmith Avatar answered Sep 20 '22 19:09

CSmith