2015-08-07 3 views
5

Я потратил эту последнюю неделю на изучение WPF, так что это все еще очень ново для меня. Одна из вещей, над которыми я работаю, - это простые анимации. В этом случае подпрыгивающий смайлик.Свойство TargetName не может быть установлено в Style Setter, так как оно установлено?

Мой план атаки:

  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> 

Хотя изменения выше, рабочий, XAML для шага # 3 Я введенную ошибку я не очень понимаю. Вот измененный XAML, который не работает: «Имя_целевого_объекта свойство не может быть установлен на Стиль сеттер Линия 20 Позиция 79.»

<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> 

ошибка

Если я не могу установить его в стиле, как его установить?

ответ

7

Ну получается, что вы не можете установить Storyboard.TargetName в Style.Setter, потому что это стиль и отвлекается. Следовательно, ссылка через имя не допускается, так как «нет ложки». Поэтому я упал 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 позволило бы нормальные триггеры, а не просто событие вызывает в коллекции, спасибо MS за делая жизнь болезненной, э гм я имею в виду удовольствие. Потому что мне нужны были оба, я должен был это исправить.

1

Вот пример вашей анимации, примененной к Button. Вероятно, это не совсем тот ответ, который вы ищете, поскольку он не имеет многоразовых ресурсов. Я только что переместил TransformGroup, Trigger и Storyboard в управление. Я еще раз взглянуть ...

<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> 
+0

Спасибо за пример кнопки. Это заставило меня задуматься о применении анимации к родительскому объекту, а не ко всем отдельным объектам. Это был лучший курс действий. – WillG