2016-02-25 3 views
1

TLDR версияWPF пользовательский шаблонный ListBox показывает неправильный цвет на IsSelected

В-приложении WPF, работает на Windows 10, у меня есть ListBox с помощью пользовательского шаблона, включая спецификации для цвета текста переднего плана, когда элемент IsSelected становится истинным. Цвет должен быть # FFBF00, но отображается намного светлее или «вымывается». Если я изменил цвет на что-то еще, я получаю тот же эффект (похожий цвет, но легче). Другие цвета в приложении отображаются правильно (так что это не проблема отображения).

Из того, что я нашел (см. Связанные проблемы), это связано с изменениями, внесенными в Windows 8 (или связанной версией .NET Framework), и мне еще предстоит найти решение или обходное решение.

Подробности

Вот пользовательский стиль/шаблон для 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> 

Вот скриншот результата:

Washed out color, as displayed

Вот что он должен выглядеть (только эскиз, только Yello ж цвет шрифта важно здесь, игнорировать другие различия):

The correct color

Похожие вопросы

Так любые идеи для решения или обходные пути? Я надеюсь, что вам не придется писать полностью настраиваемый элемент управления (но это может быть то, к чему оно сводится).

ответ

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 (1, я считаю). Поэтому, когда общая анимация заканчивается и реализует HoldEnd, ColorAnimation только завершил часть перехода к окончательному цвету, поэтому он отображает другой цвет, который «близок» к желаемому цвету.

Решение этой проблемы составило просто явно устанавливая 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> 
Смежные вопросы