2010-06-14 112 views
1

我正在做一個表面應用程序。 在那裏我有一個像公告板一樣的地方,裏面貼着新聞的小卡片。 點擊後,他們應該飛出董事會並擴大規模。 我的故事板運行良好,除了第一次運行。這不是一個平滑的動畫,但它立即縮放到最終大小,這與orientation-property一樣。只是中心屬性似乎表現正確。WPF Storyboard運行良好,除了第一次運行。爲什麼?

這是我的故事板的一個例子這樣做:

  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; 

這有什麼錯呢?

回答

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動畫作品可靠,因爲它實際上將其從值與當前值:即使News1.Center = new Point(250,400)一旦動畫開始

moveCenter.From = News1.ActualCenter;  
moveCenter.To = new Point(250, 400); 

因此,動畫總是開始於老中心。

解決方案

正如您將「從」您PointAnimation,你還可以設置你的其他動畫的初始值。這是通過在時間= 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)

+0

那麼,需要讓你困惑的一點是: 當我只是做正常的故事板,你無法移動scatterviewsitems(我忘了​​告訴你,他們是scatterviewitems,我想,我很抱歉。 ..)稍後。他們被困在他們的位置上。 所以我不得不添加「changeHeight.FillBehavior = FillBehavior.Stop;」。 但現在又出現了另一個問題: 項目跳回到它們來自的地方。 所以我不得不添加「News1.Center =新點(250,400);」的東西。 而這些並不是他們開始的觀點。他們從其他價值觀開始。 我有第二個故事板,相反。 – sofri 2010-06-16 06:39:18

+0

因此,我第一次點擊該項目,它跳出來,第二次點擊將使它跳回到公告板。 所以它運作良好,但不是第一次點擊它。除了它跳出來,就像它應該。 希望我能更好地解釋這一次;) – sofri 2010-06-16 06:41:50

+0

謝謝。現在我更好地理解了這個問題。我已經重寫了我的答案,以解釋發生了什麼以及如何解決它。 – 2010-06-16 16:43:27

0

另一種解決辦法可能是使用FillBehavior.HoldEnd,然後勾到Storyboard.Completed事件:

  • 設置本地值,你本來
  • 呼叫Storyboard.Remove

這也將有從屬性可以訪問本地值的優點。

相關問題