无法在不可变对象实例上设置不透明度的动画

时间:2015-04-21 00:23:26

标签: .net wpf xaml

我想制作带风格的自定义按钮。

<Grid>
<Button x:Name="btnRun" Style="{StaticResource ButtonStyle}" Content="Run"
Click="btn_Run" />
</Grid>

样式的动画取决于鼠标位置。动画需要改变DropShadowEffect的不透明度。但这不起作用。在运行时,当用户将鼠标悬停在按钮程序上时抛出异常:

  

无法为不可变对象实例上的Opacity设置动画

这个问题有解决方法吗?

<Window.Resources>
    <DropShadowEffect x:Key="dropShadow" x:Name="dropName" Color="red"  ShadowDepth="0" BlurRadius="42" Direction="10"  />
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Effect" Value="{StaticResource dropShadow}" />
        <Setter Property="Background" Value="Red"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <ControlTemplate.Resources>

                        <Storyboard x:Key="myStoryboard">
                            <DoubleAnimationUsingKeyFrames
                                                Storyboard.Target= "{StaticResource ResourceKey=dropShadow}"
                                                Storyboard.TargetProperty="Opacity"
                                                Duration="0:0:1.6"
                                                RepeatBehavior="Forever">
                                <LinearDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                                <LinearDoubleKeyFrame KeyTime="0:0:0.8" Value="1"/>
                                <LinearDoubleKeyFrame KeyTime="0:0:1.6" Value="0"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>                            
                    </ControlTemplate.Resources>
                    <Grid>
                        <Path Fill="{TemplateBinding Background}"
                        Data="M 241,200 
          A 20,20 0 0 0 200,240
          C 210,250 240,270 240,270
          C 240,270 260,260 280,240
          A 20,20 0 0 0 239,200" Margin="0,0,0,-15" Stretch="Fill" />
                        <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      HorizontalAlignment="{TemplateBinding HorizontalAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource myStoryboard}" />
                            </Trigger.EnterActions>
                            <Trigger Property="IsMouseOver" Value="False">                                
                        </Trigger>                            
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>            
    </Style>
</Window.Resources>

1 个答案:

答案 0 :(得分:0)

您无法为StaticResource设置动画,因此关键是在ControlTemplate中指定DropShadowEffect,然后您可以在Storyboard / DoubleAnimationUsingKeyFrames中引用它:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

        <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Red"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <ControlTemplate.Resources>
                            <Storyboard x:Key="myStoryboard">
                                <DoubleAnimationUsingKeyFrames
                                                Storyboard.TargetName= "dropName"
                                                Storyboard.TargetProperty="Opacity"
                                                Duration="0:0:1.6"
                                                RepeatBehavior="Forever">
                                    <LinearDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                                    <LinearDoubleKeyFrame KeyTime="0:0:0.8" Value="1"/>
                                    <LinearDoubleKeyFrame KeyTime="0:0:1.6" Value="0"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </ControlTemplate.Resources>
                        <Grid>
                            <Grid.Effect>
                                <DropShadowEffect x:Name="dropName" Color="red"  ShadowDepth="0" BlurRadius="42" Direction="10"  />                                        
                            </Grid.Effect>
                            <Path Fill="{TemplateBinding Background}"
                        Data="M 241,200 
          A 20,20 0 0 0 200,240
          C 210,250 240,270 240,270
          C 240,270 260,260 280,240
          A 20,20 0 0 0 239,200" Margin="0,0,0,-15" Stretch="Fill" />
                            <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      HorizontalAlignment="{TemplateBinding HorizontalAlignment}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Trigger.EnterActions>
                                    <BeginStoryboard Name="BeginStoryboard" Storyboard="{StaticResource myStoryboard}" />
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <RemoveStoryboard BeginStoryboardName="BeginStoryboard" />
                                </Trigger.ExitActions>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <Button  Style="{StaticResource ButtonStyle}" Content="Run"  />
    </Grid>
</Window>