Анимация wpf - событие нажатия мыши не работает
Существует синий прямоугольник, перемещающийся с левой стороны окна вправо на разное расстояние каждый раз.
Если щелкнуть прямоугольник или анимация завершена, прямоугольник снова начнет двигаться с левой стороны.
Если щелкнуть прямоугольник, его цвет станет зеленым с продолжительностью 0,3 с.
Но событие MouseDown, по-видимому, не запускало ColorAnimation, и расстояние перемещения / длительность прямоугольника также не были правильными.
private int i;
private Storyboard hitTargetStoryboard;
private List<double> disList;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
disList = new List<double>{.......}; // init with a list of values.
/* Create a rectangle */
Rectangle rect = new Rectangle();
this.RegisterName("rect", rect);
rect.Height = this.ActualHeight;
rect.Width = 50;
Canvas.SetTop(rect, 0);
Canvas.SetLeft(rect, 0);
/* Fill rect with a solid brush */
SolidColorBrush targetRectBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("targetRectBrush", targetRectBrush);
rect.Fill = targetRectBrush;
/* Add mouse down event */
rect.MouseDown += Rect_MouseDown;
/* Add rect to Canvas */
myCanvas.Children.Add(rect);
/* Create ColorAnimation to change color smoothly */
ColorAnimation hitCA = new ColorAnimation();
hitCA.To = Colors.Green;
hitCA.Duration = TimeSpan.FromSeconds(0.3);
hitCA.Completed += HitCA_Completed;
/* Create storyboard and add ColorAnimation to it */
hitTargetStoryboard = new Storyboard();
Storyboard.SetTargetName(hitCA, "targetRectBrush");
Storyboard.SetTargetProperty(hitCA, new PropertyPath(SolidColorBrush.ColorProperty));
hitTargetStoryboard.Children.Add(hitCA);
i = 0;
TargetAnimation(i);
}
/* move the rect from 0--disList[i] */
private void TargetAnimation(int i)
{
(this.FindName("rect") as Rectangle).Fill = Brushes.Blue;
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = disList[i];
da.Duration = TimeSpan.FromSeconds(5);
Storyboard.SetTargetName(da, "rect");
Storyboard.SetTargetProperty(da, new PropertyPath(Canvas.LeftProperty));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(da);
storyboard.Completed += Storyboard_Completed;
storyboard.Begin(this);
}
/* If rect clicked, it will change color to green */
private void Rect_MouseDown(object sender, MouseButtonEventArgs e)
{
hitTargetStoryboard.Begin(this);
}
/* After color changed, rect starts over */
private void HitCA_Completed(object sender, EventArgs e)
{
TargetAnimation(++i);
}
/* If rect not clicked, it will start over */
private void Storyboard_Completed(object sender, EventArgs e)
{
TargetAnimation(++i);
}
ОБНОВИТЬ:
delete: (this.FindName ("rect") как Rectangle).ill = Brushes.Blue;
добавить: hitCA.From = Colors.Blue;
ColorAnimation работает хорошо.
Еще:
Если я удалю Storyboard_Completed
или же HitCA_Completed
движение прямоугольника идет хорошо. Хотя, если у меня есть и то и другое, движение идет не в ту сторону.
ОБНОВЛЕНИЕ 2:
редактировать: storyboard.Begin(this, true)
в TargetAnimation(int i)
метод.
добавлять: stroyboard.Stop(this)
в HitCA_Completed
метод.
без настройки isControallable
быть true
раскадровка не будет управляемой.
РЕШИТЬ
1 ответ
Ваша проблема здесь:
(this.FindName("rect") as Rectangle).Fill = Brushes.Blue;
Прежде всего, было бы намного проще сделать rect
поле и установите Fill
собственность напрямую:
rect.Fill = Brushes.Blue;
Это не поможет вашей цветовой анимации. Вы настроили анимацию для работы с targetRectBrush
- который больше не заполняет rect
так как вы только что заменили его. Удаление этой строки оживляет цвет.
ОБНОВИТЬ
Вот слегка подправленная версия:
public partial class MainWindow
{
private int i;
private Storyboard hitTargetStoryboard;
private List<double> disList;
private Rectangle rect;
public MainWindow()
{
InitializeComponent();
Loaded += Window_Loaded;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
disList = new List<double> {10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; // init with a list of values.
/* Create a rectangle */
rect = new Rectangle();
this.RegisterName("rect", rect);
rect.Height = this.ActualHeight;
rect.Width = 50;
Canvas.SetTop(rect, 0);
Canvas.SetLeft(rect, 0);
/* Fill rect with a solid brush */
SolidColorBrush targetRectBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("targetRectBrush", targetRectBrush);
rect.Fill = targetRectBrush;
/* Add mouse down event */
rect.MouseDown += Rect_MouseDown;
/* Add rect to Canvas */
myCanvas.Children.Add(rect);
/* Create ColorAnimation to change color smoothly */
ColorAnimation hitCA = new ColorAnimation
{
From = Colors.Blue, // (Instead of setting Fill to Blue)
To = Colors.Green,
Duration = TimeSpan.FromSeconds(0.3),
FillBehavior = FillBehavior.Stop, // Returns to Blue
};
hitCA.Completed += HitCA_Completed;
/* Create storyboard and add ColorAnimation to it */
hitTargetStoryboard = new Storyboard();
Storyboard.SetTargetName(hitCA, "targetRectBrush");
Storyboard.SetTargetProperty(hitCA, new PropertyPath(SolidColorBrush.ColorProperty));
hitTargetStoryboard.Children.Add(hitCA);
i = 0;
TargetAnimation(i);
}
/* move the rect from 0--disList[i] */
private void TargetAnimation(int i)
{
i = i % disList.Count; // Don't overflow
DoubleAnimation da = new DoubleAnimation
{
From = 0,
To = disList[i],
Duration = TimeSpan.FromSeconds(5),
};
Storyboard.SetTargetName(da, "rect");
Storyboard.SetTargetProperty(da, new PropertyPath(Canvas.LeftProperty));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(da);
storyboard.Completed += Storyboard_Completed;
storyboard.Begin(this);
}
/* If rect clicked, it will change color to green */
private void Rect_MouseDown(object sender, MouseButtonEventArgs e)
{
hitTargetStoryboard.Begin(this);
}
/* After color changed, rect starts over */
private void HitCA_Completed(object sender, EventArgs e)
{
TargetAnimation(++i);
}
/* If rect not clicked, it will start over */
private void Storyboard_Completed(object sender, EventArgs e)
{
TargetAnimation(++i);
}
}
Какую проблему вы видите с расстоянием / продолжительностью?