如何为 DropShadowEffect 的不透明度设置动画?

Posted

技术标签:

【中文标题】如何为 DropShadowEffect 的不透明度设置动画?【英文标题】:How to animate Opacity of a DropShadowEffect? 【发布时间】:2010-11-28 08:44:06 【问题描述】:

我有一个使用以下样式的带有边框的 WPF 项目。计划是让发光效果在鼠标移过边框时淡入,在离开时淡出。

<Style x:Key="BorderGlow" TargetType="Border">
    <Style.Resources>
        <Storyboard x:Key="GlowOn">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(DropShadowEffect.Opacity)">
                <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="GlowOff">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(DropShadowEffect.Opacity)">
                <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Style.Resources>

    <Setter Property="CornerRadius" Value="6,1,6,1" />
    <Setter Property="BorderBrush" Value="StaticResource SelectedBorder" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Background" Value="StaticResource DeselectedBackground" />
    <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
    <Setter Property="TextBlock.Foreground" Value="StaticResource SelectedForeground" />

    <Setter Property="RenderTransform">
        <Setter.Value>
            <RotateTransform Angle="90"/>
        </Setter.Value>
    </Setter>

    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect ShadowDepth="0" BlurRadius="8" Color="#FFB0E9EF"/>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">

            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="StaticResource GlowOn"/>
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="StaticResource GlowOff"/>
            </Trigger.ExitActions>

        </Trigger>
    </Style.Triggers>
</Style>

问题是,什么都没有发生!如果我在 Storyboard TargetProperty 中将“DropShadowEffect”更改为“UIElement”,则动画会起作用,但这会使整个控件褪色。

如何仅淡化 DropShadowEffect?

【问题讨论】:

【参考方案1】:

这是西蒙回答的后续,我有一个ListView,其中ListViewItemTemplate 项目在Grid 上有一个DropShadow。长话短说,因为一个覆盖ListViewItem,选定的项目和悬停不再起作用。为了让它们工作,我必须修改Opacity,并且有两种方法可以访问Effect,具体取决于其中一种方法;我在下面展示...这里是两个 sn-ps 的 完整 示例:

在选择期间设置

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Cursor" Value="Hand"/>
            </Trigger>

            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsSelected" Value="true" />
                    <Condition Property="Selector.IsSelectionActive" Value="true" />
                </MultiTrigger.Conditions>
                <Setter Property="FontWeight" Value="Bold" />
                <Setter Property="Effect">
                    <Setter.Value>
                        <DropShadowEffect Opacity="1"/>
                    </Setter.Value>
                </Setter>
            </MultiTrigger>
        </Style.Triggers>

设置为Grid.Triggers

<Grid Background="GhostWhite">
    <Grid.Effect>
        <DropShadowEffect Opacity="0" />
    </Grid.Effect>
    <GridViewRowPresenter Content="TemplateBinding Content"
                      HorizontalAlignment="TemplateBinding HorizontalContentAlignment"
                      VerticalAlignment="TemplateBinding VerticalContentAlignment"
                      SnapsToDevicePixels="TemplateBinding SnapsToDevicePixels" />

    <Grid.Triggers>
        <EventTrigger RoutedEvent="MouseEnter">
            <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames 
                                        BeginTime="00:00:00"
                                        Storyboard.TargetProperty="(Effect).Opacity">
                            <SplineDoubleKeyFrame KeyTime="0:0:0.1" Value=".2"/>
                            <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value=".6"/>
                            <SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
            </BeginStoryboard>
        </EventTrigger>

【讨论】:

【参考方案2】:

需要注意的几点

1) 您需要针对 Border 的实际属性 - 您实际上是在尝试针对 Effect 属性的值 (DropShadowEffect),而不是属性本身。

2) 需要对PropertyPath的语法进行排序。

将您的 Storyboard.Target 属性更改为以下内容,您应该没问题:

Storyboard.TargetProperty="(Effect).Opacity"

编辑注释中注明的工作代码:

<Border BorderThickness="10" Height="100" Width="100">
    <Border.BorderBrush>
        <SolidColorBrush Color="Red"></SolidColorBrush>
    </Border.BorderBrush>
    <Border.Style>
        <Style TargetType="Border">
            <Style.Resources>
                <Storyboard x:Key="GlowOn">
                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                          Storyboard.TargetProperty="(Effect).Opacity">
                        <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
                <Storyboard x:Key="GlowOff">
                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                          Storyboard.TargetProperty="(Effect).Opacity">
                        <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </Style.Resources>

            <Setter Property="CornerRadius" Value="6,1,6,1" />
        <!--<Setter Property="BorderBrush"
                    Value="StaticResource SelectedBorder" />-->
            <Setter Property="BorderThickness" Value="1" />
        <!--<Setter Property="Background"
                    Value="StaticResource DeselectedBackground" />-->
            <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
        <!--<Setter Property="TextBlock.Foreground"
                    Value="StaticResource SelectedForeground" />-->

            <Setter Property="RenderTransform">
                <Setter.Value>
                    <RotateTransform Angle="90"/>
                </Setter.Value>
            </Setter>

            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect ShadowDepth="20"
                                      BlurRadius="8"
                                      Color="#FFB0E9EF"/>
                </Setter.Value>
            </Setter>

            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">

                    <Trigger.EnterActions>
                        <BeginStoryboard
                              Storyboard="StaticResource GlowOn"/>
                    </Trigger.EnterActions>

                    <Trigger.ExitActions>
                        <BeginStoryboard
                              Storyboard="StaticResource GlowOff"/>
                    </Trigger.ExitActions>

                </Trigger>
            </Style.Triggers>

        </Style>
    </Border.Style>
</Border>

【讨论】:

我得到一个 InvalidOperationException 因为 Effect 没有 Opacity 属性。 Effect 的值是 DropShadowEffect ,它具有我试图定位的 Opacity 属性,但正如您指出的那样,我的 XAML 是错误的。我尝试在 DropShadowEffect 上设置 x:Name 但您不能在 Styles 中使用 TargetName。 MSDN 文档中有一个关于在故事板中使用这些括号的漏洞,但我在 PropertyPath 的帮助中找到了它。但是我仍然无法解决问题。我想我需要将 Effect 转换为 DropShadowEffect 但这在 XAML 中似乎是不可能的。还有其他想法吗? 我设法让您发布的代码使用我提供的语法工作,我在一个剥离的示例应用程序中做到了这一点。我将发布我使用的内容,您也许可以从中恢复... 注意我已经删除了使用你没有提供但不会影响演示的静态资源的设置器。而且我注意到您正在尝试在您的样式中设置 TextBlock.Foreground 属性,这也不起作用。 更正:毕竟你是对的。我使用 Blend 为我生成 Storyboard XAML - “Effect.(DropShadowEffect.Opacity)”。我仍然有问题。长话短说,我在某个时候将 Effect 的 setter 移动到了 Trigger,这就是 InvalidOperationException 的原因(因为当鼠标移出边界时效果不存在)。将这个二传手移回样式中(正如我在原始帖子中所说的那样),这一切都奏效了。然后,我按照您的建议将 Storyboard 更改为“(Effect).Opacity”并且它起作用了。非常感谢西蒙!

以上是关于如何为 DropShadowEffect 的不透明度设置动画?的主要内容,如果未能解决你的问题,请参考以下文章

Silverlight & Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)

Silverlight & Blend动画设计系列七:模糊效果(BlurEffect)与阴影效果(DropShadowEffect)

如何为 UILabel 设置黑色透明? [复制]

Flutter:如何为透明容器添加阴影?

如何为 UITableView 中的选定单元格制作透明背景

如何为简单的顶点对象添加透明度?