Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Progressbar continue animation

I'm using the progress bar of WPF and set the value until the max value. But, when reached, the animation (that's the green effect) continues.

How can I stop it and have a full filled green bar, without any animation ?

for example, take this :

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <Grid>
        <ProgressBar Height="30" Name="progressBar1" VerticalAlignment="Top" Minimum="0" Maximum="100" />
    </Grid>
</Window>

and :

public partial class Window1 : Window
{
    private double _min;
    private double _max;

    public Window1()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        _min = progressBar1.Minimum;
        _max = progressBar1.Maximum;
        Thread thread = new Thread(Start);
        thread.Start();
    }

    private void Start()
    {
        for (double i = _min; i <= _max; i++)
        {
            Thread.Sleep(50);
            double value = i;
            Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => progressBar1.Value = value));
        }
    }
}

When thread has finished, I can always see the animation on the progress bar (the white effect on the green bar)

Thanks in advance for your help

like image 724
Tim Avatar asked Dec 09 '09 17:12

Tim


2 Answers

I am not entirely sure what you mean, but perhaps what you need is to set the ProgressBar's IsIndeterminate property to false. If that does not work, then please give us some code to help you further!

EDIT: The animation is part of the Windows Aero style and some designer was payed big bucks to ... err desgin it! So you cannot simply remove the animation using a property. You can alter the visual appearance of existing ProgressBars by editing their controltemplate. Below is the entire controltemplate of the WPF ProgressBar. Mind: you need all the Resources, the xmlns reference to Window.Themes and you must set a reference to the PresentationFramwork.Aero dll. I inserted a comment where you can make the change. Change the color FF000000 to 00000000 on the second and third gradientstops and the white glow disappears. I tried to implement a trigger that will show the animation at first, but stops it when Value==Maximum, but I failed. Someone else?

<Window x:Class="BlandProgressBarSpike.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="Window1" Height="300" Width="300"
    Loaded="Window_Loaded">
    <Window.Resources>
        <LinearGradientBrush x:Key="ProgressBarBackground" EndPoint="1,0" StartPoint="0,0">
            <GradientStop Color="#BABABA" Offset="0"/>
            <GradientStop Color="#C7C7C7" Offset="0.5"/>
            <GradientStop Color="#BABABA" Offset="1"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarBorderBrush" EndPoint="0,1" StartPoint="0,0">
            <GradientStop Color="#B2B2B2" Offset="0"/>
            <GradientStop Color="#8C8C8C" Offset="1"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarGlassyHighlight" EndPoint="0,1" StartPoint="0,0">
            <GradientStop Color="#50FFFFFF" Offset="0.5385"/>
            <GradientStop Color="#00FFFFFF" Offset="0.5385"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarTopHighlight" EndPoint="0,1" StartPoint="0,0">
            <GradientStop Color="#80FFFFFF" Offset="0.05"/>
            <GradientStop Color="#00FFFFFF" Offset="0.25"/>
        </LinearGradientBrush>
        <!-- This produces the whitish,moving glow-->
        <LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill" EndPoint="0,0" StartPoint="-100,0" MappingMode="Absolute">
            <GradientStop Color="#00000000" Offset="0"/>
            <GradientStop Color="#FF000000" Offset="0.4"/>
            <GradientStop Color="#FF000000" Offset="0.6"/>
            <GradientStop Color="#00000000" Offset="1"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarIndicatorDarkEdgeLeft" EndPoint="1,0" StartPoint="0,0">
            <GradientStop Color="#0C000000" Offset="0"/>
            <GradientStop Color="#20000000" Offset="0.3"/>
            <GradientStop Color="#00000000" Offset="1"/>
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarIndicatorDarkEdgeRight" EndPoint="1,0" StartPoint="0,0">
            <GradientStop Color="#00000000" Offset="0"/>
            <GradientStop Color="#20000000" Offset="0.7"/>
            <GradientStop Color="#0C000000" Offset="1"/>
        </LinearGradientBrush>
        <RadialGradientBrush x:Key="ProgressBarIndicatorLightingEffectLeft" RelativeTransform="1,0,0,1,0.5,0.5" RadiusX="1" RadiusY="1">
            <GradientStop Color="#60FFFFC4" Offset="0"/>
            <GradientStop Color="#00FFFFC4" Offset="1"/>
        </RadialGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarIndicatorLightingEffect" EndPoint="0,0" StartPoint="0,1">
            <GradientStop Color="#60FFFFC4" Offset="0"/>
            <GradientStop Color="#00FFFFC4" Offset="1"/>
        </LinearGradientBrush>
        <RadialGradientBrush x:Key="ProgressBarIndicatorLightingEffectRight" RelativeTransform="1,0,0,1,-0.5,0.5" RadiusX="1" RadiusY="1">
            <GradientStop Color="#60FFFFC4" Offset="0"/>
            <GradientStop Color="#00FFFFC4" Offset="1"/>
        </RadialGradientBrush>
        <LinearGradientBrush x:Key="ProgressBarIndicatorGlassyHighlight" EndPoint="0,1" StartPoint="0,0">
            <GradientStop Color="#90FFFFFF" Offset="0.5385"/>
            <GradientStop Color="#00FFFFFF" Offset="0.5385"/>
        </LinearGradientBrush>
        <Style x:Key="BlandStyle" TargetType="{x:Type ProgressBar}">
            <Setter Property="Foreground" Value="#01D328"/>
            <Setter Property="Background" Value="{StaticResource ProgressBarBackground}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ProgressBarBorderBrush}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ProgressBar}">
                        <Grid SnapsToDevicePixels="true" x:Name="Background">
                            <Rectangle Fill="{TemplateBinding Background}" RadiusX="2" RadiusY="2"/>
                            <Border Margin="1" Background="{StaticResource ProgressBarGlassyHighlight}" CornerRadius="2"/>
                            <Border Margin="1" Background="{StaticResource ProgressBarTopHighlight}" BorderBrush="#80FFFFFF" BorderThickness="1,0,1,1"/>
                            <Rectangle Margin="1" x:Name="PART_Track"/>
                            <Decorator HorizontalAlignment="Left" Margin="1" x:Name="PART_Indicator">
                                <Grid x:Name="Foreground">
                                    <Grid.RowDefinitions>
                                        <RowDefinition/>
                                        <RowDefinition/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition MaxWidth="15"/>
                                        <ColumnDefinition Width="0.1*"/>
                                        <ColumnDefinition MaxWidth="15"/>
                                    </Grid.ColumnDefinitions>
                                    <Rectangle x:Name="Indicator" Fill="{TemplateBinding Foreground}" Grid.ColumnSpan="3" Grid.RowSpan="2"/>
                                    <Rectangle x:Name="Animation" Fill="{TemplateBinding Foreground}" Grid.ColumnSpan="3" Grid.RowSpan="2">
                                        <Rectangle.OpacityMask>
                                            <MultiBinding>
                                                <MultiBinding.Converter>
                                                    <Microsoft_Windows_Themes:ProgressBarHighlightConverter/>
                                                </MultiBinding.Converter>
                                                <Binding Source="{StaticResource ProgressBarIndicatorAnimatedFill}"/>
                                                <Binding Path="ActualWidth" ElementName="Background"/>
                                                <Binding Path="ActualHeight" ElementName="Background"/>
                                            </MultiBinding>
                                        </Rectangle.OpacityMask>
                                    </Rectangle>
                                    <Rectangle Margin="1,1,0,1" x:Name="LeftDark" Fill="{StaticResource ProgressBarIndicatorDarkEdgeLeft}" RadiusX="1" RadiusY="1" Grid.RowSpan="2"/>
                                    <Rectangle Margin="0,1,1,1" x:Name="RightDark" Fill="{StaticResource ProgressBarIndicatorDarkEdgeRight}" RadiusX="1" RadiusY="1" Grid.Column="2" Grid.RowSpan="2"/>
                                    <Rectangle x:Name="LeftLight" Fill="{StaticResource ProgressBarIndicatorLightingEffectLeft}" Grid.Column="0" Grid.Row="2"/>
                                    <Rectangle x:Name="CenterLight" Fill="{StaticResource ProgressBarIndicatorLightingEffect}" Grid.Column="1" Grid.Row="2"/>
                                    <Rectangle x:Name="RightLight" Fill="{StaticResource ProgressBarIndicatorLightingEffectRight}" Grid.Column="2" Grid.Row="2"/>
                                    <Border x:Name="Highlight1" Grid.ColumnSpan="3" Grid.RowSpan="2" Background="{StaticResource ProgressBarIndicatorGlassyHighlight}"/>
                                    <Border x:Name="Highlight2" Grid.ColumnSpan="3" Grid.RowSpan="2" Background="{StaticResource ProgressBarTopHighlight}"/>
                                </Grid>
                            </Decorator>
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Orientation" Value="Vertical">
                                <Setter Property="LayoutTransform" TargetName="Background">
                                    <Setter.Value>
                                        <RotateTransform Angle="-90"/>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="LayoutTransform" TargetName="PART_Track">
                                    <Setter.Value>
                                        <RotateTransform Angle="90"/>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="LayoutTransform" TargetName="PART_Indicator">
                                    <Setter.Value>
                                        <RotateTransform Angle="90"/>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="LayoutTransform" TargetName="Foreground">
                                    <Setter.Value>
                                        <RotateTransform Angle="-90"/>
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                            <Trigger Property="IsIndeterminate" Value="true">
                                <Setter Property="Visibility" TargetName="LeftDark" Value="Collapsed"/>
                                <Setter Property="Visibility" TargetName="RightDark" Value="Collapsed"/>
                                <Setter Property="Visibility" TargetName="LeftLight" Value="Collapsed"/>
                                <Setter Property="Visibility" TargetName="CenterLight" Value="Collapsed"/>
                                <Setter Property="Visibility" TargetName="RightLight" Value="Collapsed"/>
                                <Setter Property="Visibility" TargetName="Indicator" Value="Collapsed"/>
                            </Trigger>
                            <Trigger Property="IsIndeterminate" Value="false">
                                <Setter Property="Fill" TargetName="Animation" Value="#80B5FFA9"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources> 
    <StackPanel>
        <ProgressBar Style="{StaticResource BlandStyle}" Value="{Binding Progress}" Height="30"
                     Minimum="0" Maximum="100"/>
    </StackPanel>           
</Window>
like image 167
Dabblernl Avatar answered Oct 06 '22 01:10

Dabblernl


Agreed that the "gleam" animation is confusing to some users. It CAN be removed without destroying the IsIndeterminate-functionality which Dabblernl:s answer above does.

Using the Aero style that you can find in Dabblernl:s post I replaced:

<Rectangle x:Name="Animation" Fill="{TemplateBinding Foreground}" Grid.ColumnSpan="3" Grid.RowSpan="2">
  <Rectangle.OpacityMask>
    <MultiBinding>
      <MultiBinding.Converter>
        <Microsoft_Windows_Themes:ProgressBarHighlightConverter/>
      </MultiBinding.Converter>
      <Binding Source="{StaticResource ProgressBarIndicatorAnimatedFill}"/>
      <Binding Path="ActualWidth" ElementName="Background"/>
      <Binding Path="ActualHeight" ElementName="Background"/>
    </MultiBinding>
  </Rectangle.OpacityMask>
</Rectangle>

with:

<Rectangle x:Name="Animation" Grid.ColumnSpan="3" Fill="{TemplateBinding Foreground}" Grid.RowSpan="2">
  <Rectangle.OpacityMask>
    <MultiBinding>
      <MultiBinding.Converter>
        <converters:ProgressBarHighlightOverrideConverter/>
      </MultiBinding.Converter>
      <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value"/>
      <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum"/>
      <Binding Source="{StaticResource ProgressBarIndicatorAnimatedFill}"/>
      <Binding ElementName="Background" Path="ActualWidth"/>
      <Binding ElementName="Background" Path="ActualHeight"/>
    </MultiBinding>
  </Rectangle.OpacityMask>
</Rectangle>

...and added a new MultiConverter:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using Microsoft.Windows.Themes;

namespace [Your namespace here]
{
  public class ProgressBarHighlightOverrideConverter : IMultiValueConverter
  {
    private readonly ProgressBarHighlightConverter converter = new ProgressBarHighlightConverter();

     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
     {
      if (values[0] == null || values[0] == DependencyProperty.UnsetValue || 
          values[1] == null || values[1] == DependencyProperty.UnsetValue)
      {
         return null;
      }

      var value = (Double)values[0];
      var maximum = (Double)values[1];

      return value >= maximum ? null : converter.Convert(new [] {values[2], values[3], values[4]}, targetType, parameter, culture);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
      return null;
    }
  }
}

So what I've effectively done is replace Microsoft:s ProgressBarHighlightConverter with one of my own that falls back on the original converter if and only if the progress bar:s value is lesser than that of its maximum.

like image 40
Per Jörgensen Avatar answered Oct 06 '22 00:10

Per Jörgensen