WPF / Windows 7: Disable Default Progress Bar Glow Animation
Asked Answered
P

6

8

Quick WPF question - on Win 7 (and I assume Vista) in WPF, the default progress bar does a nice little glowing "whoosh"-y animation.

I'm showing progress of about 48 things on one screen, and it's a tad overwhelming to have all of these things whooshing on you - can you disable just these animations without affecting the rest of the default animations in the application?

Paragrapher answered 6/10, 2009 at 1:36 Comment(2)
@Matthew, what is wrong in showing 48 progress bars? Have you seen an airplan cockpit? or weather man's dashboard? or any cnc machine's dashboard? not every app is only for programmers and only for it managers, i think the answer should be relevant to question rather then telling person to change his design, he is doing his job and he has not asked question like is it good to have 48 progress bars?Kelso
@Matthew, in this application 48 progress bars are appropriate, as it displays information about 48 devices that are physically being monitored in real time. I would agree with you if this was a LOB app or something.Paragrapher
E
4

I'd agree with Matthew's comment, but anyway, your answer is to apply a custom style without the animation. Here's the original style (via reflector), you can remove/tweak/whatever:

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
    <Style.Triggers>
        <Trigger Property="Orientation" Value="Vertical">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ProgressBar}">
                        <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
                            <Border BorderThickness="1,1,1,0" BorderBrush="#BEBEBE" CornerRadius="2">
                                <Border BorderThickness="1" BorderBrush="#EFEFEF" CornerRadius="1">
                                    <DockPanel Name="PART_Track" Margin="0,0,0,1" LastChildFill="false">
                                        <Decorator Name="PART_Indicator" Dock="Bottom">
                                            <Rectangle LayoutTransform="{RotateTransform Angle=-90}">
                                                <Rectangle.Fill>
                                                    <MultiBinding Converter="{theme:ProgressBarBrushConverter}">
                                                        <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
                                                        <Binding Path="IsIndeterminate" RelativeSource="{RelativeSource TemplatedParent}" />
                                                        <Binding Path="ActualHeight" ElementName="PART_Indicator" />
                                                        <Binding Path="ActualWidth" ElementName="PART_Indicator" />
                                                        <Binding Path="ActualHeight" ElementName="PART_Track" />
                                                    </MultiBinding>
                                                </Rectangle.Fill>
                                            </Rectangle>
                                        </Decorator>
                                    </DockPanel>
                                </Border>
                            </Border>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
    <Setter Property="Foreground" Value="{StaticResource [0] Ñ}" />
    <Setter Property="Background" Value="{DynamicResource {x:Static WindowBrush}}" />
    <Setter Property="BorderBrush" Value="#686868" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
                    <Border BorderThickness="1,1,1,0" BorderBrush="#BEBEBE" CornerRadius="2">
                        <Border BorderThickness="1" BorderBrush="#EFEFEF" CornerRadius="1">
                            <DockPanel Name="PART_Track" Margin="1,0,0,1" LastChildFill="false">
                                <Rectangle Name="PART_Indicator">
                                    <Rectangle.Fill>
                                        <MultiBinding Converter="{theme:ProgressBarBrushConverter}">
                                            <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
                                            <Binding Path="IsIndeterminate" RelativeSource="{RelativeSource TemplatedParent}" />
                                            <Binding Path="ActualWidth" ElementName="PART_Indicator" />
                                            <Binding Path="ActualHeight" ElementName="PART_Indicator" />
                                            <Binding Path="ActualWidth" ElementName="PART_Track" />
                                        </MultiBinding>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </DockPanel>
                        </Border>
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And the converter class:

public class ProgressBarBrushConverter : IMultiValueConverter
{
// Methods
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    Type type = typeof(double);
    if (((((values == null) || (values.Length != 5)) || ((values[0] == null) || (values[1] == null))) || (((values[2] == null) || (values[3] == null)) || ((values[4] == null) || !typeof(Brush).IsAssignableFrom(values[0].GetType())))) || ((!typeof(bool).IsAssignableFrom(values[1].GetType()) || !type.IsAssignableFrom(values[2].GetType())) || (!type.IsAssignableFrom(values[3].GetType()) || !type.IsAssignableFrom(values[4].GetType()))))
    {
        return null;
    }
    Brush brush = (Brush) values[0];
    bool flag = (bool) values[1];
    double d = (double) values[2];
    double num2 = (double) values[3];
    double num3 = (double) values[4];
    if ((((d <= 0.0) || double.IsInfinity(d)) || (double.IsNaN(d) || (num2 <= 0.0))) || (double.IsInfinity(num2) || double.IsNaN(num2)))
    {
        return null;
    }
    DrawingBrush brush2 = new DrawingBrush();
    brush2.Viewport = brush2.Viewbox = new Rect(0.0, 0.0, d, num2);
    brush2.ViewportUnits = brush2.ViewboxUnits = BrushMappingMode.Absolute;
    brush2.TileMode = TileMode.None;
    brush2.Stretch = Stretch.None;
    DrawingGroup group = new DrawingGroup();
    DrawingContext context = group.Open();
    double x = 0.0;
    double width = 6.0;
    double num6 = 2.0;
    double num7 = width + num6;
    if (flag)
    {
        int num8 = (int) Math.Ceiling((double) (d / num7));
        double num9 = -num8 * num7;
        double num10 = d * 0.3;
        brush2.Viewport = brush2.Viewbox = new Rect(num9, 0.0, num10 - num9, num2);
        TranslateTransform transform = new TranslateTransform();
        double num11 = num8 * 100;
        DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(num11));
        animation.RepeatBehavior = RepeatBehavior.Forever;
        for (int i = 1; i <= num8; i++)
        {
            double num13 = i * num7;
            animation.KeyFrames.Add(new DiscreteDoubleKeyFrame(num13, KeyTime.Uniform));
        }
        transform.BeginAnimation(TranslateTransform.XProperty, animation);
        brush2.Transform = transform;
        while ((x + width) < num10)
        {
            context.DrawRectangle(brush, null, new Rect(num9 + x, 0.0, width, num2));
            x += num7;
        }
        d = num10;
        x = 0.0;
    }
    while ((x + width) < d)
    {
        context.DrawRectangle(brush, null, new Rect(x, 0.0, width, num2));
        x += num7;
    }
    double num14 = d - x;
    if ((!flag && (num14 > 0.0)) && (Math.Abs((double) (d - num3)) < 1E-05))
    {
        context.DrawRectangle(brush, null, new Rect(x, 0.0, num14, num2));
    }
    context.Close();
    brush2.Drawing = group;
    return brush2;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
    return null;
}
}
Enchantment answered 6/10, 2009 at 4:29 Comment(1)
Has anyone actually successfully used this? I can't even get the above style to compile.Passifloraceous
L
10

Robert's answer is robust. Here is a hack (because it relies on the internal name of the element that does the glow, which is an implementation detail and may change in a subsequent version):

void SetGlowVisibility(ProgressBar progressBar, Visibility visibility) {
    var glow = progressBar.Template.FindName("PART_GlowRect", progressBar) as FrameworkElement;
    if (glow != null) glow.Visibility = visibility;
}

If how a progress bar is implemented changes, this hack may stop working.

On the other hand, a solution that completely replaces the XAML and styles may lock-in and fix colours, borders etc. and disable behaviour that might be added to a newer version of the ProgressBar in the future...

Less answered 4/8, 2011 at 11:35 Comment(0)
M
6

The simple, non-animated progress bar can be written as a Grid with two filled rectangles: the left one would be filled, say, with green color, the right one with gray.

The Grid would have two column definitions.

Changing the width of the two will make an effect of change of the progress.

Medea answered 19/1, 2010 at 10:8 Comment(0)
E
4

I'd agree with Matthew's comment, but anyway, your answer is to apply a custom style without the animation. Here's the original style (via reflector), you can remove/tweak/whatever:

<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
    <Style.Triggers>
        <Trigger Property="Orientation" Value="Vertical">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ProgressBar}">
                        <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
                            <Border BorderThickness="1,1,1,0" BorderBrush="#BEBEBE" CornerRadius="2">
                                <Border BorderThickness="1" BorderBrush="#EFEFEF" CornerRadius="1">
                                    <DockPanel Name="PART_Track" Margin="0,0,0,1" LastChildFill="false">
                                        <Decorator Name="PART_Indicator" Dock="Bottom">
                                            <Rectangle LayoutTransform="{RotateTransform Angle=-90}">
                                                <Rectangle.Fill>
                                                    <MultiBinding Converter="{theme:ProgressBarBrushConverter}">
                                                        <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
                                                        <Binding Path="IsIndeterminate" RelativeSource="{RelativeSource TemplatedParent}" />
                                                        <Binding Path="ActualHeight" ElementName="PART_Indicator" />
                                                        <Binding Path="ActualWidth" ElementName="PART_Indicator" />
                                                        <Binding Path="ActualHeight" ElementName="PART_Track" />
                                                    </MultiBinding>
                                                </Rectangle.Fill>
                                            </Rectangle>
                                        </Decorator>
                                    </DockPanel>
                                </Border>
                            </Border>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
    <Setter Property="Foreground" Value="{StaticResource [0] Ñ}" />
    <Setter Property="Background" Value="{DynamicResource {x:Static WindowBrush}}" />
    <Setter Property="BorderBrush" Value="#686868" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
                    <Border BorderThickness="1,1,1,0" BorderBrush="#BEBEBE" CornerRadius="2">
                        <Border BorderThickness="1" BorderBrush="#EFEFEF" CornerRadius="1">
                            <DockPanel Name="PART_Track" Margin="1,0,0,1" LastChildFill="false">
                                <Rectangle Name="PART_Indicator">
                                    <Rectangle.Fill>
                                        <MultiBinding Converter="{theme:ProgressBarBrushConverter}">
                                            <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
                                            <Binding Path="IsIndeterminate" RelativeSource="{RelativeSource TemplatedParent}" />
                                            <Binding Path="ActualWidth" ElementName="PART_Indicator" />
                                            <Binding Path="ActualHeight" ElementName="PART_Indicator" />
                                            <Binding Path="ActualWidth" ElementName="PART_Track" />
                                        </MultiBinding>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </DockPanel>
                        </Border>
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And the converter class:

public class ProgressBarBrushConverter : IMultiValueConverter
{
// Methods
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    Type type = typeof(double);
    if (((((values == null) || (values.Length != 5)) || ((values[0] == null) || (values[1] == null))) || (((values[2] == null) || (values[3] == null)) || ((values[4] == null) || !typeof(Brush).IsAssignableFrom(values[0].GetType())))) || ((!typeof(bool).IsAssignableFrom(values[1].GetType()) || !type.IsAssignableFrom(values[2].GetType())) || (!type.IsAssignableFrom(values[3].GetType()) || !type.IsAssignableFrom(values[4].GetType()))))
    {
        return null;
    }
    Brush brush = (Brush) values[0];
    bool flag = (bool) values[1];
    double d = (double) values[2];
    double num2 = (double) values[3];
    double num3 = (double) values[4];
    if ((((d <= 0.0) || double.IsInfinity(d)) || (double.IsNaN(d) || (num2 <= 0.0))) || (double.IsInfinity(num2) || double.IsNaN(num2)))
    {
        return null;
    }
    DrawingBrush brush2 = new DrawingBrush();
    brush2.Viewport = brush2.Viewbox = new Rect(0.0, 0.0, d, num2);
    brush2.ViewportUnits = brush2.ViewboxUnits = BrushMappingMode.Absolute;
    brush2.TileMode = TileMode.None;
    brush2.Stretch = Stretch.None;
    DrawingGroup group = new DrawingGroup();
    DrawingContext context = group.Open();
    double x = 0.0;
    double width = 6.0;
    double num6 = 2.0;
    double num7 = width + num6;
    if (flag)
    {
        int num8 = (int) Math.Ceiling((double) (d / num7));
        double num9 = -num8 * num7;
        double num10 = d * 0.3;
        brush2.Viewport = brush2.Viewbox = new Rect(num9, 0.0, num10 - num9, num2);
        TranslateTransform transform = new TranslateTransform();
        double num11 = num8 * 100;
        DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(num11));
        animation.RepeatBehavior = RepeatBehavior.Forever;
        for (int i = 1; i <= num8; i++)
        {
            double num13 = i * num7;
            animation.KeyFrames.Add(new DiscreteDoubleKeyFrame(num13, KeyTime.Uniform));
        }
        transform.BeginAnimation(TranslateTransform.XProperty, animation);
        brush2.Transform = transform;
        while ((x + width) < num10)
        {
            context.DrawRectangle(brush, null, new Rect(num9 + x, 0.0, width, num2));
            x += num7;
        }
        d = num10;
        x = 0.0;
    }
    while ((x + width) < d)
    {
        context.DrawRectangle(brush, null, new Rect(x, 0.0, width, num2));
        x += num7;
    }
    double num14 = d - x;
    if ((!flag && (num14 > 0.0)) && (Math.Abs((double) (d - num3)) < 1E-05))
    {
        context.DrawRectangle(brush, null, new Rect(x, 0.0, num14, num2));
    }
    context.Close();
    brush2.Drawing = group;
    return brush2;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
    return null;
}
}
Enchantment answered 6/10, 2009 at 4:29 Comment(1)
Has anyone actually successfully used this? I can't even get the above style to compile.Passifloraceous
C
3

You can also disable this effect in Win7 all together.

Right-click on My Computer icon on Desktop and select Properties (or press Windows Key + Pause/Break key), click on Advanced system settings link in left side pane (You can also open it by typing sysdm.cpl in RUN or start menu search box and press Enter). Now click on Settings button in Performance section:

Uncheck "Animate controls and elements inside windows", it should be the first selection.

Chuipek answered 27/10, 2009 at 22:17 Comment(1)
Thanks, in this particular case it should be limited to the application only (don't want to rely on a global OS theme change), but good infoParagrapher
V
0

Not my area, but this answer might be relevant too: Disabling progress bar animation on Vista Aero

Vested answered 14/3, 2011 at 14:10 Comment(0)
S
0

Create a shortcut to the application you are using, right click the shortcut and choose properties. Now in the compatibility tab click the "disable visual themes" checkbox.

Sprage answered 21/5, 2012 at 17:5 Comment(1)
This will affect the other animations in the applicationMicroprint

© 2022 - 2024 — McMap. All rights reserved.