none
Как создать анимацию (Storyboadrd) и применить ее к нескольким элементам? RRS feed

  • Общие обсуждения

  • Например есть следуюищй Storyboard:
    <Storyboard x:Name="sb">
    <ColorAnimation From="Red" To="Blue" Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" Duration="00:00:05"/>
    </Storyboard>
    
    

    Код ниже создает 5 эллипсов и применяет к ним анимацию:

    for (int i = 0; i < 5; i++)
    {
         Ellipse ellipse = new Ellipse();
         ellipse.Width = 100;
         ellipse.Height = 100;
         ellipse.Fill = new SolidColorBrush(Colors.Red);
         ellipse.SetValue(Canvas.LeftProperty, (double)random.Next(0, 600));
         ellipse.SetValue(Canvas.TopProperty, (double)random.Next(0, 600));
         this.LayoutRoot.Children.Add(ellipse);
         Storyboard.SetTarget(sb.Children[0], ellipse);
         this.sb.Begin();
    }
    

    Если вы запустите данный код, то получите исключение времени выполнения. Оно будет указывать на Storyboard, Storyboard должен быть остановлен перед сменой цели анимации. Это сделано намеренно и необходимо, потому как если вы установите SetTarget на второй эллипс, то анимация первого будет нарушена. В конце концов только один Storyboard может работать в этом случае.

    Лучшим решение является создание UserControl для инкапсуляции эллипса и раскадровки:

    <UserControl x:Class="ReuseAnimation.AnimatedEllipse"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  Loaded="UserControl_Loaded">
         <UserControl.Resources>
              <Storyboard x:Name="sb">
                  <ColorAnimation From="Red" To="Blue" Storyboard.TargetName="ellipse" 
    Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" 
    Duration="00:00:05"/>
              </Storyboard>
         </UserControl.Resources>
     
         <Ellipse x:Name="ellipse" Fill="Red">
      </Ellipse>
    </UserControl>
    
    
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
         sb.Begin();
    }
    
    

    Теперь на главной странице нужно всего лишь создать 5 объектов UserControl-а:

    for (int i = 0; i < 5; i++)
    {
         AnimatedEllipse ae = new AnimatedEllipse();
         ae.Width = 100;
         ae.Height = 100;
         ae.SetValue(Canvas.LeftProperty, (double)random.Next(0, 600));
         ae.SetValue(Canvas.TopProperty, (double)random.Next(0, 600));
         this.LayoutRoot.Children.Add(ae);
    }
    
    

    Такой подход создает чистый код и делает анимацию многоразовой до тех пор, пока вы хотите чтобы эллипсы были анимированы.

    Если вам нужно анимировать различные типы объектов, например эллипс и прямоугольник, вы можете изменить UserControl таким образом, чтобы он принимал параметр и создавал нужный объект динамически. Также можно создавать новый Storyboard в коде для каждого объекта для анимации. Это не требует создания UserControl.

     


    Для связи [mail]
    16 марта 2011 г. 13:52
    Модератор