wpf 动画——鼠标按下事件不起作用
wpf animation -- mouse down event doesn't work
有一个蓝色矩形从window的左侧向右侧移动,每次移动不同的距离。
点击矩形或动画完成后,矩形会再次从左侧开始移动。
点击矩形,颜色变为绿色,持续0.3秒
但是MouseDown事件好像没有启动ColorAnimation,矩形的移动distance/duration也不正确。
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);
}
更新:
删除 :(this.FindName("rect") 作为矩形).Fill = Brushes.Blue;
添加:hitCA.From = Colors.Blue;
ColorAnimation 效果很好。
还是:
如果我删除Storyboard_Completed
或HitCA_Completed
,rect 的移动很顺利。而如果我两者都有,则机芯运行方向错误。
更新 2:
编辑:storyboard.Begin(this, true)
在 TargetAnimation(int i)
方法中。
在HitCA_Completed
方法中添加:stroyboard.Stop(this)
。
不设置isControallable
为true
,故事板将无法控制。
已解决
你的问题在这里:
(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);
}
}
您发现 distance/duration 有什么问题?
有一个蓝色矩形从window的左侧向右侧移动,每次移动不同的距离。
点击矩形或动画完成后,矩形会再次从左侧开始移动。
点击矩形,颜色变为绿色,持续0.3秒
但是MouseDown事件好像没有启动ColorAnimation,矩形的移动distance/duration也不正确。
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);
}
更新:
删除 :(this.FindName("rect") 作为矩形).Fill = Brushes.Blue;
添加:hitCA.From = Colors.Blue;
ColorAnimation 效果很好。
还是:
如果我删除Storyboard_Completed
或HitCA_Completed
,rect 的移动很顺利。而如果我两者都有,则机芯运行方向错误。
更新 2:
编辑:storyboard.Begin(this, true)
在 TargetAnimation(int i)
方法中。
在HitCA_Completed
方法中添加:stroyboard.Stop(this)
。
不设置isControallable
为true
,故事板将无法控制。
已解决
你的问题在这里:
(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);
}
}
您发现 distance/duration 有什么问题?