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

Wil*_*llG 12 .net c# wpf animation xaml

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

我的攻击计划是:

  1. 做个笑脸.我做到了这一点.
  2. 在一个简单的对象上计算出弹跳动画.我做到了这一点.
  3. 摘要那个动画可以在几个地方使用(笑脸的元素).我被困在这里
  4. 将抽象的动画样式应用于笑脸的所有元素.

在第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>
Run Code Online (Sandbox Code Playgroud)

在改变上面的工作,XAML步骤#3时,我引入了一个我不太懂的错误.这是改变的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">
    <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>
Run Code Online (Sandbox Code Playgroud)

错误"无法在样式设置器上设置TargetName属性.第20行位置79".

如果我不能在样式中设置它如何设置它?

Wil*_*llG 18

事实证明,你不能设置Storyboard.TargetName一个Style.Setter因为它是一种风格而且是抽象的.因此,不允许通过名称引用"没有勺子".所以我放弃了Storyboard.TargetName,寻找另一种方式.

我确实发现Storyboard.TargetProperty你可以使用对象结构,有点像走DOM,引用你想要的对象.通过这种方式,你可以绕过这个需要Storyboard.TargetName.花费了更长的时间来按结构引用对象,因为我使用的是TransformGroupMS文档并不是最友好的文档.最后,我得到了它,并且在这里它是其他任何有同样问题的人.

<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>
Run Code Online (Sandbox Code Playgroud)

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

  • 对于那些研究 DOM-walking 功能被称为什么的人,我在“PropertyPath XAML Syntax”上找到了这个文档,它也描述了动画目标的注意事项。https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/propertypath-xaml-syntax (4认同)

Ben*_*Ben 7

我遇到这个问题是因为我正在构建一个自定义资源(一个按钮)。

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

<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>
Run Code Online (Sandbox Code Playgroud)