.NET Core Version: (e.g. 3.0 Preview1, or daily build number, use dotnet --info): All since .NET 4.5
Windows version: (winver): Any
Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? No
Problem description: WPF's ProgressBar uses a well-known named template part (GlowingRectTemplateName which is == PART_GlowRect) in order to control the indeterminate animation. Specifically it wants to stop the animation when the control becomes invisible.
Since aero2.normalcolor.xaml was introduced this no longer works as the template has no PART_GlowRect and instead triggers the animation based on the Indeterminate VisualState.
This means that for stock WPF ProgressBars with IsIndeterminate=True, the animations will run forever regardless of whether the animation is visible. This is esepcially bad on high-refresh rate monitors as the callbacks occur much more frequently and keep what could be an idle system non-idle preventing battery saving mode switches on laptops.
Actual behavior: Animations run forever
Expected behavior: Animations stop when the control becomes invisible, as the code appears to facilitate.
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace AnimationTestApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Task.Delay(2000).ContinueWith((t) =>
{
return Dispatcher.InvokeAsync(() =>
{
Grid panel = (Grid)this.FindName("HostElement_Collapsed");
if (panel != null)
panel.Visibility = Visibility.Collapsed;
}).Task;
});
}
}
}
Placing a breakpoint on System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames.GetCurrentValueCore with a 'when hit' action that simply say prints a line to the debugger shows that even when the animation is invisible the callbacks continue.
Changing the markup such that IsIndeterminate is bound to IsVisible and rerunning the repro with the same printing breakpoint shows then the animations stop as the control becomes invisible (as the VisualState = Indeterminate becomes no longer true)
dotnet --info
): All since .NET 4.5winver
): AnyProblem description: WPF's ProgressBar uses a well-known named template part (GlowingRectTemplateName which is == PART_GlowRect) in order to control the indeterminate animation. Specifically it wants to stop the animation when the control becomes invisible.
Since aero2.normalcolor.xaml was introduced this no longer works as the template has no PART_GlowRect and instead triggers the animation based on the Indeterminate VisualState.
Specifically see
Code here: https://github.com/dotnet/wpf/blob/89d172db0b7a192de720c6cfba5e28a1e7d46123/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ProgressBar.cs#L62
and here: https://github.com/dotnet/wpf/blob/89d172db0b7a192de720c6cfba5e28a1e7d46123/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ProgressBar.cs#L220
and template here (other templates have similar issues, other than aero.normalcolor.xaml): https://github.com/dotnet/wpf/blob/89d172db0b7a192de720c6cfba5e28a1e7d46123/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Aero2/Themes/Aero2.NormalColor.xaml#L4428
This means that for stock WPF ProgressBars with IsIndeterminate=True, the animations will run forever regardless of whether the animation is visible. This is esepcially bad on high-refresh rate monitors as the callbacks occur much more frequently and keep what could be an idle system non-idle preventing battery saving mode switches on laptops.
Actual behavior: Animations run forever
Expected behavior: Animations stop when the control becomes invisible, as the code appears to facilitate.
Minimal repro:
MainWindow.xaml
MainWindow.xaml.cs
Placing a breakpoint on System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames.GetCurrentValueCore with a 'when hit' action that simply say prints a line to the debugger shows that even when the animation is invisible the callbacks continue.
Changing the markup such that IsIndeterminate is bound to IsVisible and rerunning the repro with the same printing breakpoint shows then the animations stop as the control becomes invisible (as the VisualState = Indeterminate becomes no longer true)