这几天一直在对原来的WPF应用程序进行改进和重构,准备为应用程序加入一些动画操作,但问题来了!
经由动画改变的属性不能变化了,只能再次通过动画更改。
这也太不爽了吧。搞一两个小时,终于找到了解决的办法。
下面给出主要代码:
foreach (UIElement control in canvas.Children)
{
//UserControl
RealTimeChartFlexible chartFlexible = (RealTimeChartFlexible)control;
//开始动画
//注册名字(对于UserControl来说很关键的一步,本人试了很久)
chartFlexible.RegisterName("chartFlexible", chartFlexible);
//left
DoubleAnimation leftAni = new DoubleAnimation();
leftAni.To = colNum * pWidth;
leftAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(leftAni, "chartFlexible");
Storyboard.SetTargetProperty(leftAni, new PropertyPath(Canvas.LeftProperty));
//top
DoubleAnimation topAni = new DoubleAnimation();
topAni.To = rowNum * pHeight;
topAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(topAni, "chartFlexible");
Storyboard.SetTargetProperty(topAni, new PropertyPath(Canvas.TopProperty));
//width
DoubleAnimation WidthAni = new DoubleAnimation();
WidthAni.To = pWidth;
WidthAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(WidthAni, "chartFlexible");
Storyboard.SetTargetProperty(WidthAni, new PropertyPath(RealTimeChartFlexible.WidthProperty));
//height
DoubleAnimation HeightAni = new DoubleAnimation();
HeightAni.To = pHeight;
HeightAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(HeightAni, "chartFlexible");
Storyboard.SetTargetProperty(HeightAni, new PropertyPath(RealTimeChartFlexible.HeightProperty));
Storyboard sb = new Storyboard();
sb.Children.Add(leftAni);
sb.Children.Add(topAni);
sb.Children.Add(HeightAni);
sb.Children.Add(WidthAni);
storys.Add(sb);
sb.Completed += new EventHandler(sb_Completed);
sb.Begin(chartFlexible, true);
//chartFlexible.Width = pWidth;
//chartFlexible.Height = pHeight;
chartFlexible.myOriginalWidth = pWidth;
chartFlexible.myOriginalHeight = pHeight;
chartFlexible.myTop = rowNum * pHeight;
chartFlexible.myLeft = colNum * pWidth;
//Canvas.SetLeft(chartFlexible, chartFlexible.myLeft);
//Canvas.SetTop(chartFlexible, chartFlexible.myTop);
rowNum++;
if (rowNum == row)
{
colNum++;
rowNum = 0;
}
}
{
//UserControl
RealTimeChartFlexible chartFlexible = (RealTimeChartFlexible)control;
//开始动画
//注册名字(对于UserControl来说很关键的一步,本人试了很久)
chartFlexible.RegisterName("chartFlexible", chartFlexible);
//left
DoubleAnimation leftAni = new DoubleAnimation();
leftAni.To = colNum * pWidth;
leftAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(leftAni, "chartFlexible");
Storyboard.SetTargetProperty(leftAni, new PropertyPath(Canvas.LeftProperty));
//top
DoubleAnimation topAni = new DoubleAnimation();
topAni.To = rowNum * pHeight;
topAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(topAni, "chartFlexible");
Storyboard.SetTargetProperty(topAni, new PropertyPath(Canvas.TopProperty));
//width
DoubleAnimation WidthAni = new DoubleAnimation();
WidthAni.To = pWidth;
WidthAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(WidthAni, "chartFlexible");
Storyboard.SetTargetProperty(WidthAni, new PropertyPath(RealTimeChartFlexible.WidthProperty));
//height
DoubleAnimation HeightAni = new DoubleAnimation();
HeightAni.To = pHeight;
HeightAni.Duration = new Duration(new TimeSpan(0, 0, 1));
Storyboard.SetTargetName(HeightAni, "chartFlexible");
Storyboard.SetTargetProperty(HeightAni, new PropertyPath(RealTimeChartFlexible.HeightProperty));
Storyboard sb = new Storyboard();
sb.Children.Add(leftAni);
sb.Children.Add(topAni);
sb.Children.Add(HeightAni);
sb.Children.Add(WidthAni);
storys.Add(sb);
sb.Completed += new EventHandler(sb_Completed);
sb.Begin(chartFlexible, true);
//chartFlexible.Width = pWidth;
//chartFlexible.Height = pHeight;
chartFlexible.myOriginalWidth = pWidth;
chartFlexible.myOriginalHeight = pHeight;
chartFlexible.myTop = rowNum * pHeight;
chartFlexible.myLeft = colNum * pWidth;
//Canvas.SetLeft(chartFlexible, chartFlexible.myLeft);
//Canvas.SetTop(chartFlexible, chartFlexible.myTop);
rowNum++;
if (rowNum == row)
{
colNum++;
rowNum = 0;
}
}
关键就在于Storybroad的Begin方法的第二个参数,可以使动画为可控制,以便动画完成后移除。
void sb_Completed(object sender, EventArgs e)
{
int index = 0;
foreach (object control in canvas.Children)
{
RealTimeChartFlexible chartFlexible = (RealTimeChartFlexible)control;
double top = Canvas.GetTop(chartFlexible);
double left = Canvas.GetLeft(chartFlexible);
double height = chartFlexible.Height;
double width = chartFlexible.Width;
storys[index].Remove(chartFlexible);
chartFlexible.Height = height;
chartFlexible.Width = width;
Canvas.SetLeft(chartFlexible, left);
Canvas.SetTop(chartFlexible, top);
index++;
}
}
{
int index = 0;
foreach (object control in canvas.Children)
{
RealTimeChartFlexible chartFlexible = (RealTimeChartFlexible)control;
double top = Canvas.GetTop(chartFlexible);
double left = Canvas.GetLeft(chartFlexible);
double height = chartFlexible.Height;
double width = chartFlexible.Width;
storys[index].Remove(chartFlexible);
chartFlexible.Height = height;
chartFlexible.Width = width;
Canvas.SetLeft(chartFlexible, left);
Canvas.SetTop(chartFlexible, top);
index++;
}
}
storys是一个Storyboard的表,执行了Remove方法后UIElement的位置会回到做动画之前,要在执行Remove之前保存位置,呵呵
就这样,问题解决!
如果各位有更好的办法可以留言给我,谢谢!