2009-04-22 11 views
0

Я преподавал WPF через «Продажи/Griffiths» «Программирование WPF», и я нашел его отличным ресурсом, но я пытаюсь взять некоторые из понятий, которые они ввели я и дальше делаю шаг вперед, и я сталкиваюсь с концептуальной ошибкой в ​​том, как объединить фигуры, чтобы выполнить то, что я пытаюсь сделать.Удаление FrameworkElements на завершение анимации

В этом упражнении я пытаюсь создать самозавершающиеся анимации; FrameworkElement s, которые создаются Событиями, выполняют анимацию, а затем удаляют себя. У меня возникли проблемы с выяснением того, как перезвонить родительскому FrameworkElement из события animation.Completed.

Я задал этот вопрос изначально только с использованием DoubleAnimation s, которые не были сохранены, а не являются частью Storyboard. С тех пор я добавил Storyboard и сделал Storyboard и ресурсы прямоугольника, чтобы их можно было повторно использовать.

Вот что я до сих пор:
.xaml:

<Window.Resources> 
    <Storyboard x:Key="GrowSquare" x:Shared="False"> 
     <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" By="-50" Duration="0:0:2"/> 
     <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" By="-50" Duration="0:0:2"/> 
     <DoubleAnimation Storyboard.TargetProperty="(Ellipse.Width)" By="100" Duration="0:0:2"/> 
     <DoubleAnimation Storyboard.TargetProperty="(Ellipse.Height)" By="100" Duration="0:0:2"/> 
    </Storyboard> 
    <Rectangle x:Key="MyRect" x:Shared="False" Width="20" Height="20"> 
    </Rectangle> 
</Window.Resources> 
<Canvas x:Name="myCanvas" MouseMove="myCanvas_MouseMove" Background="White"/> 

.cs:

public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      lastFire = DateTime.Now; 
     } 

     DateTime lastFire; 

     private void myCanvas_MouseMove(object sender, MouseEventArgs e) 
     { 
      DateTime nowTime = DateTime.Now; 
      TimeSpan T = nowTime.Subtract(lastFire); 

      if (T.TotalMilliseconds > 200) 
      { 
       lastFire = nowTime; 
       Random Rand = new Random(); 

       Rectangle myRect = (Rectangle)FindResource("MyRect"); 
       myRect.Fill = new SolidColorBrush(Color.FromRgb((byte)Rand.Next(256), (byte)Rand.Next(256), (byte)Rand.Next(256))); 
       Point myLoc = e.GetPosition(myCanvas); 
       Canvas.SetLeft(myRect, myLoc.X - 10); 
       Canvas.SetTop(myRect, myLoc.Y - 10); 
       myCanvas.Children.Add(myRect); 

       Storyboard SB = (Storyboard)FindResource("GrowSquare"); 
       SB.Completed += new EventHandler(SB_Completed); 
       SB.Begin(myRect); 
      } 

     } 

     void SB_Completed(object sender, EventArgs e) 
     { 
      myCanvas.Children.RemoveAt(0); 
     } 
    } 

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

Однако я хотел бы реализовать анимации, которые занимают случайное количество времени, что означает, что анимация не всегда начинается и заканчивается в том же порядке. Как-то в событии SB_Completed я хотел бы получить доступ к элементу управления, к которому он был вызван, но пока не могу найти путь к нему.

Есть ли способ получить из Media.Animation.ClockGroup, который вызывает событие SB_Completed для элемента управления, вызываемого анимацией?

ответ

3

изменить строку, в которой назначить обработчик события к этому:

SB.Completed += (s,e) => myCanvas.Children.Remove(myRect); 
+0

Я даже не думал в этом направлении раньше. Благодарю. Это отлично поработало. –

 Смежные вопросы

  • Нет связанных вопросов^_^