La propriété TargetName ne peut pas être définie sur un Setter de Style, alors comment est-elle définie?
j'ai passé la semaine dernière à explorer WPF donc c'est encore très nouveau pour moi. Une des choses sur lesquelles je travaille est de simples animations. Dans ce cas, un smiley rebondissant.
mon plan d'attaque est:
- faites un smiley. Je l'ai fait.
- calculez l'animation rebondissante sur un objet simple. Je l'ai fait.
- abstrait cette animation pour qu'elle puisse être utilisée en plusieurs endroits (les éléments du smiley). Je suis coincé ici.
- appliquer le style d'animation abstraite à tous les éléments du smiley.
après l'étape #2 j'ai eu le XAML de travail suivant:
<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>
en modifiant ce qui précède, en travaillant, XAML pour l'étape #3 j'ai introduit une erreur que je ne comprends pas vraiment. Voici le XAML modifié qui ne fonctionne pas:
<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>
l'erreur " la propriété TargetName ne peut pas être définie sur un setter de Style. Ligne 20, Position 79."
Si je ne peux pas le régler dans le style comment puis-je le mettre?
3 réponses
eh Bien il s'avère que vous ne pouvez pas définir Storyboard.TargetName
dans un Style.Setter
parce que c'est un style abstrait. Par conséquent, une référence via le nom n'est pas autorisée en tant que "il n'y a pas de cuillère". Donc j'ai laissé tomber Storyboard.TargetName
et chercha un autre moyen.
je n'ai trouver que dans Storyboard.TargetProperty
vous pouvez utiliser la structure de l'objet, un peu comme marcher sur le DOM, pour référencer l'objet que vous voulez. De cette façon, vous contournez le besoin de Storyboard.TargetName
. Il a fallu plus de temps pour établir le référencement de l'objet par structure parce que j'étais à l'aide d'un TransformGroup
et Mme docs n'est pas la plus amicale des docs. Enfin, je l'ai eu et le voici pour tous ceux qui ont le même problème.
<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>
bien sûr, je l'ai donné sur le style tout à fait si Button.Triggers
aurait permis des déclencheurs normaux et pas seulement des déclencheurs d'événements dans la collection, merci MS pour rendre la vie douloureuse, euh je veux dire amusant. Parce que j'avais besoin des deux, je devais régler ça.
Voici un exemple de votre animation appliquée à un Button
. Ce n'est probablement pas tout à fait la réponse que vous recherchez car il n'a pas de ressources réutilisables. J'ai juste déplacé le TransformGroup
, Trigger
et Storyboard
dans le contrôle. Je vais prendre un autre regard...
<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>
j'ai eu ce problème parce que je construisais une ressource personnalisée (un bouton).
C'était mon problème, et sa solution:
<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>