There is a blue rectangle moving from left side of the window to right for different distance every time.
Either clicking the rectangle or the animation completed, the rectangle will start moving again from left side.
If rectangle is clicked, the color of it will turn to be green with a duration of 0.3s.
But the MouseDown event seemed not start the ColorAnimation and the moving distance/duration of rectangle was not correct neither.
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);
}
UPDATE:
delete :(this.FindName("rect") as Rectangle).Fill = Brushes.Blue;
add : hitCA.From = Colors.Blue;
ColorAnimation works well.
Still:
If I delete Storyboard_Completed
or HitCA_Completed
, the movement of rect goes well. While If I have both, the movement runs a wrong way.
UPDATE 2:
edit: storyboard.Begin(this, true)
in TargetAnimation(int i)
method.
add: stroyboard.Stop(this)
in HitCA_Completed
method.
without setting isControallable
to be true
, the storyboard will not be controllable.
SOLVED
Your problem is here:
(this.FindName("rect") as Rectangle).Fill = Brushes.Blue;
First of all, it would be much easier to make rect
a field and set the Fill
property directly:
rect.Fill = Brushes.Blue;
That wouldn't help your color animation, though. You've set up an animation to work with targetRectBrush
-- which no longer fills rect
since you've just replaced it. Removing that one line animates the color.
UPDATE
Here's a slightly tweaked version:
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);
}
}
What problem are you seeing with distance/duration?