用于'ComboBoxItem`s的动画的高光效果

时间:2017-02-19 16:43:14

标签: wpf animation combobox triggers mouseevent

我希望ComboBoxItem元素中ComboBox s的背景上有一个简单的动画效果。当指针位于指定的颜色上时,项目应突出显示已定义的颜色,并在指针离开时恢复为原始状态。

这是我的模板

<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对我来说并不陌生,但我发现依赖项对象非常混乱。特别是使用多种方法来操作或动画属性。 打开Dropbox时有一个NullReferenceException。这对我来说很清楚。根本没有链接到故事板的依赖项对象,但在这种方法中,我无法在TargetName触发器中设置Style属性。

对此有何正确的解决方法?如果使用VisualSate是“原生”方法,那么我更倾向于使用触发器。

更新

这有效,但它使用触发器。我希望使用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>

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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>