2017-02-19 111 views
0

我想在ComboBox元素的背景ComboBoxItem s中获得简单的动画效果。当指针位于它上面时,项目应该用定义的颜色高亮显示,并在指针离开时恢复到其原始状态。带有ComboBoxItem的动画的高光效果

这是我的模板

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}"> 
    <Setter Property="SnapsToDevicePixels" Value="true" /> 
    <Setter Property="OverridesDefaultStyle" Value="true" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ComboBoxItem}"> 
       <Border x:Name="Border" 
         Padding="2" 
         SnapsToDevicePixels="true"> 
        <Border.Style> 
         <Style TargetType="{x:Type Border}"> 
          <Style.Triggers> 
           <Trigger Property="IsMouseOver" Value="True"> 
            <Trigger.EnterActions> 
             <BeginStoryboard> 
              <Storyboard> 
               <ColorAnimation Duration="0:0:0.01" 
                   Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" 
                   To="#FFA7ACD4" /> 
              </Storyboard> 
             </BeginStoryboard> 
            </Trigger.EnterActions> 
            <Trigger.ExitActions> 
             <BeginStoryboard> 
              <Storyboard> 
               <ColorAnimation Duration="0:0:0.6" 
                   Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" 
                   To="White" /> 
              </Storyboard> 
             </BeginStoryboard> 
            </Trigger.ExitActions> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </Border.Style> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="SelectionStates"> 
          <VisualState x:Name="Unselected" /> 
          <VisualState x:Name="Selected"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
               Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource ColorItemSelectedBackground}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="SelectedUnfocused"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
              Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" 
              Value="{StaticResource SelectedUnfocusedColor}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <ContentPresenter /> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

我有一个触发是要走的路预感。 我试过使用VisualSateGroups同时使用MouseEnterMouseOverMouseEnter什么都没做,MouseOver没有恢复到原来的状态。 我重新思考这个例子反映了我想达到的最好。

WPF对我来说并不陌生,但我发现依赖对象非常混乱。特别是使用可用于操作或动画属性的多种方法。 打开保管箱后有一个NullReferenceException。这对我来说很清楚。根本没有链接到故事板的依赖项对象,但是在这种方法中,我无法在Style触发器中设置TargetName属性。

这是什么方法?如果使用VisualSate是“本地”方法,那么我更喜欢这个触发器。

UPDATE

这工作,但它使用的触发器。我更喜欢使用VisualStateGroups仅用于学习目的的解决方案。

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}"> 
    <Setter Property="SnapsToDevicePixels" Value="true" /> 
    <Setter Property="OverridesDefaultStyle" Value="true" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ComboBoxItem}"> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsHighlighted" Value="true"> 
         <Trigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:0.01" 
                Storyboard.TargetName="Border" 
                Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                To="#FFA7ACD4" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </Trigger.EnterActions> 

         <Trigger.ExitActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:0.6" 
                Storyboard.TargetName="Border" 
                Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                To="White" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </Trigger.ExitActions> 
        </Trigger> 
       </ControlTemplate.Triggers> 
       <Border x:Name="Border" 
         Padding="2" 
         SnapsToDevicePixels="true" 
         Background="White"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="SelectionStates"> 
          <VisualState x:Name="Unselected" /> 
          <VisualState x:Name="Selected"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
               Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource ColorItemSelectedBackground}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="SelectedUnfocused"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
              Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" 
              Value="{StaticResource SelectedUnfocusedColor}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <ContentPresenter /> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

回答

1

试试这个:

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}"> 
    <Setter Property="SnapsToDevicePixels" Value="true" /> 
    <Setter Property="OverridesDefaultStyle" Value="true" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ComboBoxItem}"> 
       <Border x:Name="Border" 
            Padding="2" 
            SnapsToDevicePixels="true" 
            Background="White"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="Common"> 
          <VisualState x:Name="Normal"> 
           <Storyboard> 
            <ColorAnimation 
                 Storyboard.TargetName="Border" 
                 Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                 To="White" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:1" 
                 Storyboard.TargetName="Border" 
                 Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                 To="#FFA7ACD4" /> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="SelectionStates"> 
          <VisualState x:Name="Unselected" /> 
          <VisualState x:Name="Selected"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                        Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="Red" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="SelectedUnfocused"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                        Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="Green" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <ContentPresenter /> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
+0

这很好,但唯一的问题是'Common'中的故事板''Normal'覆盖'SelectionStates'>'Selected'中的故事板。鼠标离开后,所选项目的视觉提示不会重新应用。有任何想法吗? – DerpyNerd

+0

将选定状态移至公共组。 – mm8

+0

我很感谢你的努力。但我不明白。如果这是必需的,那么为什么SelectionStates组甚至存在? – DerpyNerd

0

作为一个侧面说明,以MM8的答案。这是突出显示所选项目并突出显示鼠标指针下方项目的唯一方法。

VisualStateManager似乎无法返回到Selected状态,因为它被Normal状态覆盖。

因此,我已将VisualStateManager删除,转而采用多触发方式。

<Color x:Key="ItemBackground">White</Color> 
<Color x:Key="ItemSelectedBackground">#FFC5CBF9</Color> 
<Color x:Key="ItemMouseOverBackground">#FFA7ACD4</Color> 

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}"> 
    <Setter Property="SnapsToDevicePixels" Value="true" /> 
    <Setter Property="OverridesDefaultStyle" Value="true" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ComboBoxItem}"> 

       <ControlTemplate.Triggers> 
        <!-- Trigger for hightlighting items on MouseOver --> 
        <MultiTrigger> 
         <MultiTrigger.Conditions> 
          <Condition Property="IsHighlighted" Value="true" /> 
          <Condition Property="IsSelected" Value="false" /> 
         </MultiTrigger.Conditions> 
         <MultiTrigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:0.01" 
                Storyboard.TargetName="Border" 
                Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                To="{StaticResource ItemMouseOverBackground}" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </MultiTrigger.EnterActions> 

         <MultiTrigger.ExitActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:0.2" 
                Storyboard.TargetName="Border" 
                Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                To="{StaticResource ItemBackground}" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </MultiTrigger.ExitActions> 
        </MultiTrigger> 
        <!-- Trigger for hightlighting selected items on MouseOver --> 
        <MultiTrigger> 
         <MultiTrigger.Conditions> 
          <Condition Property="IsHighlighted" Value="true" /> 
          <Condition Property="IsSelected" Value="true" /> 
         </MultiTrigger.Conditions> 
         <MultiTrigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:0.01" 
                Storyboard.TargetName="Border" 
                Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                To="{StaticResource ItemMouseOverBackground}" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </MultiTrigger.EnterActions> 

         <MultiTrigger.ExitActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <ColorAnimation Duration="0:0:0.2" 
                Storyboard.TargetName="Border" 
                Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 
                To="{StaticResource ItemSelectedBackground}" /> 
           </Storyboard> 
          </BeginStoryboard> 
         </MultiTrigger.ExitActions> 
        </MultiTrigger> 
       </ControlTemplate.Triggers> 

       <Border 
        x:Name="Border" 
        Padding="2" 
        SnapsToDevicePixels="true" 
        Background="White"> 
        <!--<VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames 
             Storyboard.TargetName="Border" 
             Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ItemBackground}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames 
             Storyboard.TargetName="Border" 
             Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ItemMouseOverBackground}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="SelectionStates"> 
          <VisualState x:Name="Unselected" /> 
          <VisualState x:Name="Selected"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames 
             Storyboard.TargetName="Border" 
             Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" Value="{StaticResource ItemSelectedBackground}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="SelectedUnfocused"> 
           <Storyboard> 
            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" 
              Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"> 
             <EasingColorKeyFrame KeyTime="0" 
              Value="{StaticResource SelectedUnfocusedColor}" /> 
            </ColorAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups>--> 
        <ContentPresenter /> 
       </Border> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style>