我在做Surface应用程序。 在那里,我有一个类似于公告牌的东西,其上贴有新闻的小卡片。 点击它们会飞出棋盘并扩大规模。 我的故事板运行良好,除了第一次运行。它不是一个平滑的动画,但它立即缩放到它的最终大小,它与orientation-property相同。只是中心属性似乎行为正确。
这是我的一个故事板的例子:
Storyboard stb = new Storyboard();
PointAnimation moveCenter = new PointAnimation();
DoubleAnimationUsingKeyFrames changeWidth = new DoubleAnimationUsingKeyFrames();
DoubleAnimationUsingKeyFrames changeHeight = new DoubleAnimationUsingKeyFrames();
DoubleAnimationUsingKeyFrames changeOrientation = new DoubleAnimationUsingKeyFrames();
moveCenter.From = News1.ActualCenter;
moveCenter.To = new Point(250, 400);
moveCenter.Duration = new Duration(TimeSpan.FromSeconds(1.0));
moveCenter.FillBehavior = FillBehavior.Stop;
stb.Children.Add(moveCenter);
Storyboard.SetTarget(moveCenter, News1);
Storyboard.SetTargetProperty(moveCenter, new PropertyPath(ScatterViewItem.CenterProperty));
changeWidth.Duration = TimeSpan.FromSeconds(1);
changeWidth.KeyFrames.Add(new EasingDoubleKeyFrame(266, KeyTime.FromTimeSpan(new System.TimeSpan(0, 0, 1))));
changeWidth.FillBehavior = FillBehavior.Stop;
stb.Children.Add(changeWidth);
Storyboard.SetTarget(changeWidth, News1);
Storyboard.SetTargetProperty(changeWidth, new PropertyPath(FrameworkElement.WidthProperty));
changeHeight.Duration = TimeSpan.FromSeconds(1);
changeHeight.KeyFrames.Add(new EasingDoubleKeyFrame(400, KeyTime.FromTimeSpan(new System.TimeSpan(0, 0, 1))));
changeHeight.FillBehavior = FillBehavior.Stop;
stb.Children.Add(changeHeight);
Storyboard.SetTarget(changeHeight, News1);
Storyboard.SetTargetProperty(changeHeight, new PropertyPath(FrameworkElement.HeightProperty));
changeOrientation.Duration = TimeSpan.FromSeconds(1);
changeOrientation.KeyFrames.Add(new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(new System.TimeSpan(0, 0, 1))));
changeOrientation.FillBehavior = FillBehavior.Stop;
stb.Children.Add(changeOrientation);
Storyboard.SetTarget(changeOrientation, News1);
Storyboard.SetTargetProperty(changeOrientation, new PropertyPath(ScatterViewItem.OrientationProperty));
stb.Begin(this);
News1.Center = new Point(250, 400);
News1.Orientation = 0;
News1.Width = 266;
News1.Height = 400;
Pin1.Visibility = Visibility.Collapsed;
news1IsOutside = true;
Scroll1.IsEnabled = true;
它出了什么问题?
答案 0 :(得分:2)
问题
问题的本质是你正在调用stb.Begin()然后立即更改News1.Width等。不幸的是stb.Begin()不能保证立即启动动画:有时它会在调度员回调。
发生的事情是,第一次执行故事板时,stb.Begin()会调度一个调度程序回调来启动动画并立即返回。接下来的四行代码会更新值:
News1.Center = new Point(250, 400);
News1.Orientation = 0;
News1.Width = 266;
News1.Height = 400;
当动画实际上在调度程序回调中开始时,它们会看到新值并将其用作起始值。这会导致对象看起来立即跳转到新值。
例如,changeWidth声明一个关键帧,将值设置为266:
changeWidth.KeyFrames.Add(new EasingDoubleKeyFrame(266, ...
后来初始宽度设置为266:
News1.Width = 266;
因此,如果故事板开始延迟,宽度将从266到266动画。换句话说,它不会改变。如果您以后使用另一个动画将News1.Width更改为266以外的其他动画,然后运行changeWidth动画,它将起作用。
您的moveCenter动画可靠地运行,因为它实际上将其From值设置为当前值:
moveCenter.From = News1.ActualCenter;
moveCenter.To = new Point(250, 400);
因此动画总是从旧中心开始,即使动画开始时News1.Center = new Point(250,400)
也是如此。
解决方案
就像在PointAnimation上设置“From”一样,您也可以在其他动画中设置初始值。这是通过在时间= 0处添加关键帧来指定当前宽度来完成的:
changeWidth.Duration = TimeSpan.FromSeconds(1);
changeWidth.KeyFrames.Add(new DiscreteDoubleKeyframe(News1.Width, KeyTime.Paced));
changeWidth.KeyFrames.Add(new EasingDoubleKeyFrame(266, KeyTime.Paced));
如果有两个关键帧,此代码使用KeyTime.Paced
自动产生0%和100%的事实。实际上,将第一帧设置为KeyFrame.Paced
始终等同于KeyTime.FromTimeSpan(TimeSpan.Zero)
。
答案 1 :(得分:0)
另一个解决方案可能是使用FillBehavior.HoldEnd
,然后连接到Storyboard.Completed
事件并且:
Storyboard.Remove
这样做的好处还在于可以从属性中访问本地值。