无法在样式设置器上设置TargetName属性,那么它是如何设置的?

时间:2015-08-07 00:17:58

标签: wpf xaml animation

上周我一直在探索WPF,所以对我来说这仍然是一个新手。我正在研究的一件事是简单的动画。在这种情况下,一个弹跳的笑脸。

我的攻击计划是:

  1. 笑脸。我做到了。
  2. 在一个简单的物体上计算出弹跳动画。我做到了。
  3. 摘要动画可以在几个地方使用(笑脸的元素)。我被困在这里。
  4. 将抽象的动画风格应用于笑脸的所有元素。
  5. 在第2步之后,我进行了以下工作XAML:

    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
            Title="Test Window" Height="350" Width="620">
        <Grid>
            <Canvas Margin="0,180,0,0">
                <Ellipse Canvas.Left="10" Canvas.Top="10" Width="100" Height="100" Stroke="Blue" StrokeThickness="4" Fill="Aqua" />
                <Ellipse Canvas.Left="30" Canvas.Top="12" Width="60" Height="30">
                    <Ellipse.Fill>
                        <LinearGradientBrush StartPoint="0.45,0" EndPoint="0.5, 0.9">
                            <GradientStop Offset="0.2" Color="DarkMagenta" />
                            <GradientStop Offset="0.7" Color="Transparent" />
                        </LinearGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Ellipse Canvas.Left="33" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
                <Ellipse Canvas.Left="40" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
                <Ellipse Canvas.Left="68" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
                <Ellipse Canvas.Left="75" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
                <Path Name="mouth" Stroke="Blue" StrokeThickness="4" Data="M 35,75 Q 55,90 80,75 " />
            </Canvas>
            <Grid Margin="100,5,0,0" Width="75" Height="300">
                <Canvas>
                    <Ellipse Height="40" Width="40" x:Name="theBall" Canvas.Left="16">
                        <Ellipse.Fill>
                            <RadialGradientBrush GradientOrigin="0.75,0.25">
                                <GradientStop Color="Yellow" Offset="0.0" />
                                <GradientStop Color="Red" Offset="1.0" />
                            </RadialGradientBrush>
                        </Ellipse.Fill>
                        <Ellipse.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform x:Name="aniSquash"/>
                                <TranslateTransform x:Name="aniBounce"/>
                            </TransformGroup>
                        </Ellipse.RenderTransform>
                        <Ellipse.Triggers>
                            <EventTrigger RoutedEvent="Loaded">
                                <BeginStoryboard>
                                    <Storyboard SpeedRatio="2.0">
                                        <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniBounce" Storyboard.TargetProperty="Y" RepeatBehavior="Forever">
                                            <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
                                            <SplineDoubleKeyFrame Value="260" KeyTime="0:0:2.2" KeySpline="0, 0, 0.5, 0"/>
                                            <LinearDoubleKeyFrame Value="260" KeyTime="0:0:2.25"/>
                                            <SplineDoubleKeyFrame Value="120" KeyTime="0:0:4.5" KeySpline="0, 0, 0, 0.5"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleX" RepeatBehavior="Forever">
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                            <LinearDoubleKeyFrame Value="1.3" KeyTime="0:0:2.25"/>
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleY" RepeatBehavior="Forever">
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                            <LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:2.25"/>
                                            <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                        </Ellipse.Triggers>
                    </Ellipse>
                    <Rectangle Height="5" Canvas.Left="10" Canvas.Top="285" Width="55" Fill="Black"/>
                </Canvas>
            </Grid>
        </Grid>
    </Window>
    

    在改变上面的步骤#3的XAML时,我引入了一个我不太懂的错误。以下是无效的XA​​ML:

    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
            Title="Test Window" Height="350" Width="620">
        <Window.Resources>
            <TransformGroup x:Key="aniBounceAndSquash">
                <ScaleTransform x:Name="aniSquash"/>
                <TranslateTransform x:Name="aniBounce"/>
            </TransformGroup>
            <Style x:Key="styleBounceAndSquash" TargetType="FrameworkElement">
                <Setter Property="RenderTransform" Value="{StaticResource aniBounceAndSquash}" />
                <Style.Triggers>
                    <EventTrigger RoutedEvent="Loaded">
                        <BeginStoryboard>
                            <Storyboard SpeedRatio="2.0">
                                <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniBounce" Storyboard.TargetProperty="Y" RepeatBehavior="Forever">
                                    <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
                                    <SplineDoubleKeyFrame Value="260" KeyTime="0:0:2.2" KeySpline="0, 0, 0.5, 0"/>
                                    <LinearDoubleKeyFrame Value="260" KeyTime="0:0:2.25"/>
                                    <SplineDoubleKeyFrame Value="120" KeyTime="0:0:4.5" KeySpline="0, 0, 0, 0.5"/>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleX" RepeatBehavior="Forever">
                                    <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                    <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                    <LinearDoubleKeyFrame Value="1.3" KeyTime="0:0:2.25"/>
                                    <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleY" RepeatBehavior="Forever">
                                    <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                                    <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                                    <LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:2.25"/>
                                    <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <Grid>
            <Canvas Margin="0,180,0,0">
                <Ellipse Canvas.Left="10" Canvas.Top="10" Width="100" Height="100" Stroke="Blue" StrokeThickness="4" Fill="Aqua" />
                <Ellipse Canvas.Left="30" Canvas.Top="12" Width="60" Height="30">
                    <Ellipse.Fill>
                        <LinearGradientBrush StartPoint="0.45,0" EndPoint="0.5, 0.9">
                            <GradientStop Offset="0.2" Color="DarkMagenta" />
                            <GradientStop Offset="0.7" Color="Transparent" />
                        </LinearGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Ellipse Canvas.Left="33" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
                <Ellipse Canvas.Left="40" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
                <Ellipse Canvas.Left="68" Canvas.Top="35" Width="20" Height="20" Stroke="Blue" StrokeThickness="3" Fill="White" />
                <Ellipse Canvas.Left="75" Canvas.Top="43" Width="6" Height="5" Fill="Black" />
                <Path Name="mouth" Stroke="Blue" StrokeThickness="4" Data="M 35,75 Q 55,90 80,75 " />
            </Canvas>
            <Grid Margin="100,5,0,0" Width="75" Height="300">
                <Canvas>
                    <Ellipse Height="40" Width="40" x:Name="theBall" Canvas.Left="16" Style="{StaticResource styleBounceAndSquash}">
                        <Ellipse.Fill>
                            <RadialGradientBrush GradientOrigin="0.75,0.25">
                                <GradientStop Color="Yellow" Offset="0.0" />
                                <GradientStop Color="Red" Offset="1.0" />
                            </RadialGradientBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                    <Rectangle Height="5" Canvas.Left="10" Canvas.Top="285" Width="55" Fill="Black"/>
                </Canvas>
            </Grid>
        </Grid>
    </Window>
    

    错误“无法在样式设定器上设置TargetName属性。第20行位置79”。

    如果我无法在样式中设置它如何设置?

3 个答案:

答案 0 :(得分:16)

事实证明,您无法在Storyboard.TargetName中设置Style.Setter,因为它是一种风格并且是抽象的。因此,不允许通过名称引用&#34;没有勺子&#34;。所以我放弃Storyboard.TargetName并寻找另一种方式。

我确实发现在Storyboard.TargetProperty中你可以使用对象结构,有点像走DOM,引用你想要的对象。通过这种方式,您可以绕过Storyboard.TargetName的需要。由于我使用的是TransformGroup而MS文档不是最友好的文档,因此需要花费更长时间才能按结构引用对象。最后,我得到了它,这里也是其他任何有同样问题的人。

<Style x:Key="buttonSmiley" TargetType="{x:Type Button}">
    <Style.Resources>
        <Storyboard x:Key="OnVisibleStoryboard">
            <DoubleAnimationUsingKeyFrames Duration="0:0:2.75" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)" >
                <LinearDoubleKeyFrame Value="75" KeyTime="0:0:0"/>
                <SplineDoubleKeyFrame Value="25" KeyTime="0:0:0.75" KeySpline="0, 0, 0.5, 0"/>
                <LinearDoubleKeyFrame Value="-25" KeyTime="0:0:1.2"/>
                <SplineDoubleKeyFrame Value="200" KeyTime="0:0:2.25" KeySpline="0, 0, 0, 0.5"/>
                <LinearDoubleKeyFrame Value="175" KeyTime="0:0:2.4" />
                <SplineDoubleKeyFrame Value="150" KeyTime="0:0:2.75" KeySpline="0, 0, 0, 0.5"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Duration="0:0:5.5" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleX)" >
                <LinearDoubleKeyFrame Value="0.01" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:1.25"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.05"/>
                <LinearDoubleKeyFrame Value="1.15" KeyTime="0:0:2.15"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.4"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.75"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Duration="0:0:5.5" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleY)" >
                <LinearDoubleKeyFrame Value="0.01" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:1.25"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.05"/>
                <LinearDoubleKeyFrame Value="0.75" KeyTime="0:0:2.2"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.4"/>
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.75"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Style.Resources>
    <Style.Triggers>
        <Trigger Property="Visibility" Value="Visible">
            <Trigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="OnLoadStoryboard_BeginStoryboard"/>
                <BeginStoryboard x:Name="OnVisibleStoryboard_BeginStoryboard" Storyboard="{StaticResource OnVisibleStoryboard}"/>
            </Trigger.EnterActions>
        </Trigger>
        <EventTrigger RoutedEvent="Button.Loaded">
            <RemoveStoryboard BeginStoryboardName="OnVisibleStoryboard_BeginStoryboard"/>
            <BeginStoryboard x:Name="OnLoadStoryboard_BeginStoryboard" Storyboard="{StaticResource OnVisibleStoryboard}"/>
        </EventTrigger>
    </Style.Triggers>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Canvas Margin="-35,-35,0,0">
                    <Ellipse Canvas.Left="10" Canvas.Top="10" Width="50" Height="50" Stroke="Blue" StrokeThickness="2" Fill="#FFD8CF15" />
                    <Ellipse Canvas.Left="18" Canvas.Top="12" Width="33" Height="15">
                        <Ellipse.Fill>
                            <LinearGradientBrush StartPoint="0.45,0" EndPoint="0.5, 0.9">
                                <GradientStop Offset="0.2" Color="DarkMagenta" />
                                <GradientStop Offset="0.7" Color="Transparent" />
                            </LinearGradientBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                    <Ellipse Canvas.Left="17" Canvas.Top="25" Width="10" Height="10" Stroke="Blue" StrokeThickness="2" Fill="White" />
                    <Ellipse Canvas.Left="20" Canvas.Top="28" Width="3" Height="3" Fill="Black" />
                    <Ellipse Canvas.Left="34" Canvas.Top="25" Width="10" Height="10" Stroke="Blue" StrokeThickness="2" Fill="White" />
                    <Ellipse Canvas.Left="37" Canvas.Top="28" Width="3" Height="3" Fill="Black" />
                    <Path Name="mouth" Stroke="Blue" StrokeThickness="2" Data="M 20,43 Q 27,53 40,44" />
                </Canvas>
            </DataTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="RenderTransform">
        <Setter.Value>
            <TransformGroup>
                <TranslateTransform />
                <ScaleTransform />
            </TransformGroup>
        </Setter.Value>
    </Setter>
</Style>

当然,如果Button.Triggers允许普通触发而不是集合中的JUST事件触发器,我会完全放弃这种风格,谢谢MS让生活变得痛苦,呃我的意思很有趣。因为我需要两个,所以我必须解决这个问题。

答案 1 :(得分:2)

出现此问题是因为我正在构建自定义资源(按钮)。

这是我的问题及其解决方案:

<Style x:Key="MyButton" TargetType="{x:Type Button}">
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                ...
                <ControlTemplate.Triggers>
                    ==> should have put triggers here <==
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        ==> not here <==
    </Style.Triggers>
</Style>

答案 2 :(得分:1)

以下是应用于Button的动画示例。它可能不是你正在寻找的答案,因为它没有可重复使用的资源。我刚刚将TransformGroupTriggerStoryboard移到了控件中。我会再看看......

<Button Style="{StaticResource styleBounceAndSquash}">
    <Button.RenderTransform>
        <TransformGroup>
            <ScaleTransform x:Name="aniSquash"/>
            <TranslateTransform x:Name="aniBounce"/>
        </TransformGroup>
    </Button.RenderTransform>
    <Button.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard SpeedRatio="2.0">
                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniBounce" Storyboard.TargetProperty="Y" RepeatBehavior="Forever">
                        <LinearDoubleKeyFrame Value="120" KeyTime="0:0:0"/>
                        <SplineDoubleKeyFrame Value="260" KeyTime="0:0:2.2" KeySpline="0, 0, 0.5, 0"/>
                        <LinearDoubleKeyFrame Value="260" KeyTime="0:0:2.25"/>
                        <SplineDoubleKeyFrame Value="120" KeyTime="0:0:4.5" KeySpline="0, 0, 0, 0.5"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleX" RepeatBehavior="Forever">
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                        <LinearDoubleKeyFrame Value="1.3" KeyTime="0:0:2.25"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                    </DoubleAnimationUsingKeyFrames>
                    <DoubleAnimationUsingKeyFrames Duration="0:0:4.5" Storyboard.TargetName="aniSquash" Storyboard.TargetProperty="ScaleY" RepeatBehavior="Forever">
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2"/>
                        <LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:2.25"/>
                        <LinearDoubleKeyFrame Value="1" KeyTime="0:0:2.5"/>
                    </DoubleAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>