TLDR版本
在Windows 10上运行的WPF应用程序中,我有一个带有自定义模板的ListBox,包括当项IsSelected变为true时文本Foreground颜色的规范。颜色应该是#FFBF00,但显示更轻或“褪色”。如果我将颜色更改为其他颜色,我会得到相同的效果(颜色相似,但更亮)。应用程序中的其他颜色正确显示(因此它不是显示问题)。
从我发现的(参见相关问题),这似乎与Windows 8(或相关的.NET框架版本)中的更改有关,我还没有找到解决方案或解决方法。
详情
以下是ListBox的自定义样式/模板:
<Style x:Key="WorkflowRibbon" TargetType="ListBox">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border ClipToBounds="True">
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<DataTemplate.Resources>
<AlternationConverter x:Key="BackgroundBrushes">
<SolidColorBrush Color="White" Opacity="0.65"/>
<SolidColorBrush Color="White" Opacity="0.45"/>
<SolidColorBrush Color="White" Opacity="0.31"/>
<SolidColorBrush Color="White" Opacity="0.20"/>
<SolidColorBrush Color="White" Opacity="0.10"/>
</AlternationConverter>
<Storyboard x:Key="PhaseSelectedAnimation" Duration="0:0:0.25">
<ColorAnimation Storyboard.TargetProperty="Color"
Storyboard.TargetName="ForegroundBrush"
To="#ffbf00">
<ColorAnimation.EasingFunction>
<PowerEase Power="2"/>
</ColorAnimation.EasingFunction>
</ColorAnimation>
<DoubleAnimation Storyboard.TargetProperty="Scale"
Storyboard.TargetName="RibbonLabel"
To="1.1">
<DoubleAnimation.EasingFunction>
<PowerEase Power="2"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="PhaseDeselectedAnimation" Duration="0:0:0.25">
<ColorAnimation Storyboard.TargetProperty="Color"
Storyboard.TargetName="ForegroundBrush">
<ColorAnimation.EasingFunction>
<PowerEase Power="2"/>
</ColorAnimation.EasingFunction>
</ColorAnimation>
<DoubleAnimation Storyboard.TargetProperty="Scale"
Storyboard.TargetName="RibbonLabel">
<DoubleAnimation.EasingFunction>
<PowerEase Power="2"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</DataTemplate.Resources>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="PhaseSelectedStoryboard" Storyboard="{StaticResource PhaseSelectedAnimation}"/>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard x:Name="PhaseDeselectedStoryboard" Storyboard="{StaticResource PhaseDeselectedAnimation}"/>
</DataTrigger.ExitActions>
</DataTrigger>
</DataTemplate.Triggers>
<local:WorkflowRibbonLabel WorkflowPhase="{Binding}"
x:Name="RibbonLabel"
BorderThickness="0"
Scale="1.0"
Background="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=(ItemsControl.AlternationIndex), Converter={StaticResource BackgroundBrushes}}">
<local:WorkflowRibbonLabel.Foreground>
<SolidColorBrush x:Name="ForegroundBrush" Color="#ffffff" Opacity="1"/>
</local:WorkflowRibbonLabel.Foreground>
</local:WorkflowRibbonLabel>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
<Setter Property="AlternationCount" Value="5"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="-1"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
</Style.Setters>
</Style>
除了颜色问题之外,这种风格在各个方面都非常有效。请注意这个动画:
<ColorAnimation Storyboard.TargetProperty="Color"
Storyboard.TargetName="ForegroundBrush"
To="#ffbf00">
<ColorAnimation.EasingFunction>
<PowerEase Power="2"/>
</ColorAnimation.EasingFunction>
</ColorAnimation>
通过IsSelected触发器调用并导致颜色更改(只是错误的颜色):
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="PhaseSelectedStoryboard" Storyboard="{StaticResource PhaseSelectedAnimation}"/>
</DataTrigger.EnterActions>
以下是结果的屏幕截图:
以下是应该的样子(只是草图,这里只有黄色字体颜色很重要,忽略其他差异):
相关问题
那么解决方案或解决方法的想法是什么?我希望避免编写一个完全自定义的控件(但这可能是它归结为)。
答案 0 :(得分:0)
我明白了。 Windows 8的东西是红鲱鱼。关键代码段在这里:
<Storyboard x:Key="PhaseDeselectedAnimation" Duration="0:0:0.25">
<ColorAnimation Storyboard.TargetProperty="Color"
Storyboard.TargetName="ForegroundBrush">
<ColorAnimation.EasingFunction>
<PowerEase Power="2"/>
</ColorAnimation.EasingFunction>
</ColorAnimation>
我认为ColorAnimation
会从父Duration
继承其Storyboard
。这个假设是不正确的。显然,ColorAnimation
将恢复为默认Duration
(1s,我相信)。因此,当整个动画完成并实现HoldEnd
时,ColorAnimation
只完成了部分过渡到最终颜色的部分,这就是为什么它会显示另一种颜色,即#34;关闭&#34;所需的颜色。
解决此问题只需在Duration
上明确设置ColorAnimation
属性,就像这样:
<Storyboard x:Key="PhaseDeselectedAnimation" Duration="0:0:0.25">
<ColorAnimation Storyboard.TargetProperty="Color"
Duration="0:0:0.25"
Storyboard.TargetName="ForegroundBrush">
<ColorAnimation.EasingFunction>
<PowerEase Power="2"/>
</ColorAnimation.EasingFunction>
</ColorAnimation>