Я преподавал 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 для элемента управления, вызываемого анимацией?
Я даже не думал в этом направлении раньше. Благодарю. Это отлично поработало. –