Skip to content

Commit

Permalink
Progressbar: Fix issue with color changing when updating value while …
Browse files Browse the repository at this point in the history
  • Loading branch information
Kinnara committed Dec 20, 2020
1 parent c225dd6 commit 18eefa0
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 30 deletions.
28 changes: 28 additions & 0 deletions ModernWpf/Controls/Primitives/BindingProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Windows;

namespace ModernWpf.Controls.Primitives
{
public class BindingProxy : Freezable
{
#region Value

public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value),
typeof(object),
typeof(BindingProxy));

public object Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}

#endregion

protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
}
}
57 changes: 36 additions & 21 deletions ModernWpf/ProgressBar/ProgressBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,31 +270,38 @@ private void OnShowErrorPropertyChanged(DependencyPropertyChangedEventArgs args)

private void UpdateStates(bool useTransitions = true)
{
if (ShowError && IsIndeterminate)
{
VisualStateManager.GoToState(this, s_IndeterminateErrorStateName, useTransitions);
}
else if (ShowError)
{
VisualStateManager.GoToState(this, s_ErrorStateName, useTransitions);
}
else if (ShowPaused && IsIndeterminate)
{
VisualStateManager.GoToState(this, s_IndeterminatePausedStateName, useTransitions);
}
else if (ShowPaused)
{
VisualStateManager.GoToState(this, s_PausedStateName, useTransitions);
}
else if (IsIndeterminate)
if (IsIndeterminate)
{
if (ShowError)
{
VisualStateManager.GoToState(this, s_IndeterminateErrorStateName, true);
}
else if (ShowPaused)
{
VisualStateManager.GoToState(this, s_IndeterminatePausedStateName, true);
}
else
{
VisualStateManager.GoToState(this, s_IndeterminateStateName, true);
}
UpdateWidthBasedTemplateSettings();
VisualStateManager.GoToState(this, s_IndeterminateStateName, useTransitions);
}
else if (!IsIndeterminate)
else
{
VisualStateManager.GoToState(this, s_DeterminateStateName, useTransitions);
if (ShowError)
{
VisualStateManager.GoToState(this, s_ErrorStateName, true);
}
else if (ShowPaused)
{
VisualStateManager.GoToState(this, s_PausedStateName, true);
}
else
{
VisualStateManager.GoToState(this, s_DeterminateStateName, true);
}
}

}

private void SetProgressBarIndicatorWidth()
Expand All @@ -315,7 +322,14 @@ private void SetProgressBarIndicatorWidth()

// Adds "Updating" state in between to trigger RepositionThemeAnimation Visual Transition
// in ProgressBar.xaml when reverting back to previous state
VisualStateManager.GoToState(this, s_UpdatingStateName, true);
if (ShowError)
{
VisualStateManager.GoToState(this, s_UpdatingWithErrorStateName, true);
}
else
{
VisualStateManager.GoToState(this, s_UpdatingStateName, true);
}

if (IsIndeterminate)
{
Expand Down Expand Up @@ -473,5 +487,6 @@ private void ReapplyIndeterminateStoryboard()
const string s_IndeterminatePausedStateName = "IndeterminatePaused";
const string s_DeterminateStateName = "Determinate";
const string s_UpdatingStateName = "Updating";
const string s_UpdatingWithErrorStateName = "UpdatingError";
}
}
39 changes: 30 additions & 9 deletions ModernWpf/ProgressBar/ProgressBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,20 @@
x:Name="LayoutRoot"
SnapsToDevicePixels="True">
<Grid.Resources>
<primitives:BindingProxy
x:Key="SystemControlErrorTextForegroundBrushProxy"
Value="{DynamicResource SystemControlErrorTextForegroundBrush}" />
<Storyboard x:Key="UpdatingToDeterminateStoryboard">
<!-- Using a nested Storyboard to work around https://stackoverflow.com/questions/5002501 -->
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="DeterminateProgressBarIndicator" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
<DiscreteDoubleKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.IndicatorLengthDelta}" />
<SplineDoubleKeyFrame KeyTime="0:0:0.367" Value="0" KeySpline="0.1,0.9 0.2,1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="DeterminateProgressBarIndicator" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
<DiscreteDoubleKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.IndicatorLengthDelta}" />
<SplineDoubleKeyFrame KeyTime="0:0:0.367" Value="0" KeySpline="0.1,0.9 0.2,1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="UpdatingErrorToErrorStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="DeterminateProgressBarIndicator" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
<DiscreteDoubleKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.IndicatorLengthDelta}" />
<SplineDoubleKeyFrame KeyTime="0:0:0.367" Value="0" KeySpline="0.1,0.9 0.2,1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="IndeterminateStoryboard" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateProgressBarIndicator" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
Expand Down Expand Up @@ -87,7 +93,7 @@
Value="{DynamicResource SystemAccentColor}"
KeyTime="0:0:2.75" />
<LinearColorKeyFrame
Value="{DynamicResource SystemErrorTextColor}"
Value="{Binding Source={StaticResource SystemControlErrorTextForegroundBrushProxy}, Path=Value.Color}"
KeyTime="0:0:3" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Expand All @@ -106,7 +112,7 @@
<ColorAnimation
Storyboard.TargetName="DeterminateProgressBarIndicator"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="{DynamicResource SystemErrorTextColor}"
To="{Binding Source={StaticResource SystemControlErrorTextForegroundBrushProxy}, Path=Value.Color}"
Duration="0:0:0.25" />
<ColorAnimation
Storyboard.TargetName="ProgressBarRoot"
Expand Down Expand Up @@ -167,6 +173,7 @@

<VisualStateGroup.Transitions>
<VisualTransition From="Updating" To="Determinate" Storyboard="{StaticResource UpdatingToDeterminateStoryboard}" />
<VisualTransition From="UpdatingError" To="Error" Storyboard="{StaticResource UpdatingErrorToErrorStoryboard}" />
<VisualTransition From="Paused" To="Determinate">
<Storyboard>
<Storyboard>
Expand All @@ -190,6 +197,20 @@
</VisualStateGroup.Transitions>
<VisualState x:Name="Determinate" />
<VisualState x:Name="Updating" />
<VisualState x:Name="UpdatingError">
<Storyboard>
<ColorAnimation
Storyboard.TargetName="DeterminateProgressBarIndicator"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="{Binding Source={StaticResource SystemControlErrorTextForegroundBrushProxy}, Path=Value.Color}"
Duration="0:0:0.0" />
<ColorAnimation
Storyboard.TargetName="ProgressBarRoot"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="{DynamicResource SystemControlErrorBackgroundColor}"
Duration="0:0:0.0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate" Storyboard="{StaticResource IndeterminateStoryboard}" />
<VisualState x:Name="IndeterminateError" Storyboard="{StaticResource IndeterminateErrorStoryboard}" />
<VisualState x:Name="Error" Storyboard="{StaticResource ErrorStoryboard}" />
Expand Down

0 comments on commit 18eefa0

Please sign in to comment.