简化(!)示例:
<Window Background="Black">
<Button Background="#ff272727"
Content="Whatever"
Foreground="White"
Padding="16,8"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="container" Background="{TemplateBinding Background}">
<ContentPresenter Margin="{TemplateBinding Padding}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:2" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="container"
Storyboard.TargetProperty="Background.Color"
To="#33ff8000" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</Window>
将鼠标悬停在按钮上时,我希望颜色在 2 秒的时间内从
#ff272727
(不透明深灰色)过渡到 #33ff8000
(半透明橙色)。然而,实际发生的情况是,它首先非常快速地(我估计大约四分之一秒)过渡到看起来像 #ffff8000
的样子,然后在剩下的 2 秒内继续 #33ff8000
。
从本质上讲,它似乎是一个接一个地对颜色和 alpha 分量进行动画处理,而不是同时对两者进行动画处理。
有趣的是,如果我交换两种颜色的 alpha 值,即当我从半透明颜色设置动画为完全不透明颜色时,不会发生同样的事情。似乎只有当
To
颜色不透明时才会发生。
对我来说另一个有趣的观察是,即使使用这个故事板也会发生完全相同的现象:
<Storyboard>
<DoubleAnimation Storyboard.TargetName="container"
Storyboard.TargetProperty="Background.Opacity"
To="0.2" />
<ColorAnimation Storyboard.TargetName="container"
Storyboard.TargetProperty="Background.Color"
To="#ffff8000" />
</Storyboard>
这也将首先对颜色进行动画处理,然后对不透明度进行动画处理...
我做错了什么还是这是一个已知问题?如果是这样,是否有任何已知的解决方法?
这其实是你的眼睛欺骗了你。光是一件棘手的事情,它的强度不是线性的(对数或接近平方取决于我们正在讨论的光强度/颜色的哪个方面)。此外,从灰色到橙色的步骤比减少不透明度要短得多,因此您的眼睛比不透明度变化更快地察觉到这种情况发生。
这里有几个深入探讨该主题的链接:
为了用您的示例说明这种现象,我更改了您的模板以显示动画正在做什么。在下面的结果中,您可以看到它确实线性地穿过两个值。
<Button Background="#FF272700" Foreground="White" Padding="16,8" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="container" Background="{TemplateBinding Background}" Padding="16,8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Background.Color, ElementName=container}" />
<TextBlock Grid.Row="1" Text="{Binding Background.Opacity, ElementName=container}" />
</Grid>
<!--<ContentPresenter Margin="{TemplateBinding Padding}" />-->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:05" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard Changed="Storyboard_Changed">
<DoubleAnimation Storyboard.TargetName="container" Storyboard.TargetProperty="Background.Opacity" To="0.2" />
<ColorAnimation Storyboard.TargetName="container" Storyboard.TargetProperty="Background.Color" To="#ff8000" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
解决方法是分别更改动画的速度和/或起点,让它们按照您想要的方式显示。