5

我在Metro XAML應用程序中混淆了一些Storyboard。我必須在代碼中創建一個Storyboard。我想設置Storyboard.TargetPropertyCompositeTransform.Rotation無法將Storyboard.TargetProperty設置爲Metro風格應用程序中的CompositeTransform.Rotation,代碼爲

這似乎是不可能的......

我的故事板在XAML看起來是這樣的:

<Storyboard> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="grid"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
     <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="60"/ 
    </DoubleAnimationUsingKeyFrames> 
</Storyboard> 

我想創建類似的東西。
重要提示:我不想重新創建這個確切的故事板。我在自定義ContentControl的代碼中,所以thisControl,並且沒有「網格」來定位動畫。目標是控制本身,其中有CompositeTransform以前設置。

到目前爲止我的代碼是這樣的:

var turnSB = new Storyboard(); 

var doubleAnim = new DoubleAnimationUsingKeyFrames(); 
doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(0), Value = currentAngle }); 
doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(500), Value = targetAngle }); 

turnSB.Children.Add(doubleAnim); 

Storyboard.SetTarget(doubleAnim, this.RenderTransform); 
Storyboard.SetTargetProperty(doubleAnim, "(CompositeTransform.Rotation)"); 

turnSB.Begin(); 

只要它擊中Begin方法我得到一個異常說(CompositeTransform.Rotation)不能得到解決。所以我猜我沒有得到物業路徑非常正確。我嘗試了不同的變體,但根據PropertyPaths,這應該是正確的,不是嗎? :S

如果這是一個無法解決的問題,我願意在解決方法建議...

編輯:

我想我已經解決了這個問題現在。我有一些有趣的發現,雖然...

如果我做一個用戶控件,我幾乎可以做任何事情。一切正常,我可以設置Storyboard.Target屬性,並且動畫可以正確播放。

但是,如果我使用自定義控件,或從另一個控件(比如ContentControl)繼承,我無法從代碼啓動Storyboard,僅在某些情況下。

例如:如果我製作一個Storyboard(在XAML中定義)來爲Rotation(或任何轉換屬性)製作動畫並嘗試從代碼開始,我會得到上述異常。但是,如果我爲一個簡單的屬性創建動畫,比如說不透明度,它就可以正常工作。
(我用UserControl做了同樣的工作,它工作。)

有人可以解釋這個嗎?

+0

我有同樣的問題,有從電網控制一個類繼承,故事簡單地贏得」開始。 – 2013-01-16 09:40:13

+0

有一點需要注意的是,Grid不是從Control繼承的,所以它不是一個真正的自定義控件。 – 2013-01-18 05:27:05

+0

我沒有使用Grid,我從ContentControl繼承。 xaml來自之前的嘗試,我有一個擁有網格的UserControl,並且這是動畫的目標。但是對於這種情況,目標應該是控制本身。其中 - 如果你仔細閱讀 - 我在'重要'一節中描述。 – Tenshiko 2013-01-29 16:37:20

回答

4

MSDN docs看起來您需要設置整個字符串路徑。因此,對於在XAML中所描述的動畫,你就需要設置TargetProperty這樣

Storyboard.SetTargetProperty(doubleAnim, "(UIElement.RenderTransform).(CompositeTransform.Rotation)"); 

UPDATE: 發現這個blog post它增加了一個時間軸的故事板的一個孩子。請嘗試以下操作:

Storyboard.SetTarget(doubleAnim, this.RenderTransform); 
Storyboard.SetTargetProperty(doubleAnim, "Rotation"); // maybe "CompositeTransform.Rotation" 
storyboard.Children.Add(doubleAnim); 
+0

我試過這些的每一個組合。結果總是一樣的。 – Tenshiko 2012-08-18 19:18:34

+0

我已經得出結論,問題不在故事板設置中。事實上,您的第一個建議現在可以使用,但只能使用UserControls。我想了解更多關於這個主題的內容,也許有人可以對此有所瞭解。但如果不是,我會接受你的答案。 Thx :) – Tenshiko 2012-08-18 19:36:05

+0

那麼這是在一個自定義控件內? – 2012-08-19 04:48:20

4

我認爲你得到這個錯誤的原因是因爲你沒有實例化的自定義控件的RenderTransform財產。

public class CustomControl2 : Control 
{ 
    public CustomControl2() 
    { 
     this.DefaultStyleKey = typeof(CustomControl2); 
    } 

    protected override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
    } 

    public void RunAnimation() 
    { 
     //this.RenderTransform = new CompositeTransform(); 
     this.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x33, 0xC8, 0x9C)); 

     var turnSB = new Storyboard(); 

     var doubleAnim = new DoubleAnimationUsingKeyFrames(); 
     doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(0), Value = 10 }); 
     doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(500), Value = 30 }); 

     turnSB.Children.Add(doubleAnim); 

     Storyboard.SetTarget(doubleAnim, this.RenderTransform); 
     Storyboard.SetTargetProperty(doubleAnim, "(CompositeTransform.Rotation)"); 

     turnSB.Begin(); 
    } 
} 

注意,在上面的代碼,如果我的方法RunAnimation下注釋掉的第一行,它會拋出我,你所得到的是同樣的錯誤。

然後我在我的主頁中創建了這個控件,並創建了一個Button來啓動動畫。

private void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
    this.MyControl.RunAnimation(); 
} 

我測試了上面的代碼,它工作正常。

+0

我明白了爲什麼這應該起作用,但正如我在我的原始文章中說過的,我設置了轉換(請再次閱讀「重要」部分)。而且,我能用更簡單的解決方案重現相同的效果。讓我再檢查一次,然後回到你身邊。 – Tenshiko 2013-01-29 16:30:19

+0

我能想到的一件事是,也許你在調用「OnApplyTemplate」之前啓動了分區? – 2013-01-30 03:49:13

1

解決它

的問題是在路徑的youre使用元素,其具有從其延伸到所述屬性本身的父類派生。我有我自己的控制工作,所以做了一個小例子,你可以複製粘貼(未經測試的代碼):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Media.Animation; 

namespace CustomControls 
{ 
    /// <summary> 
    /// Author: Frank Wolferink 
    /// Note: example is untested and comes as is. I hope it save's you the time i lost figering this out 
    /// </summary> 
    public class CustomControl : Control 
    { 

     private Storyboard _compositeTransformExampleStoryBoard; 

     private const string TRANSLATE_X_TARGET = "Control.RenderTransform.CompositeTransform.TranslateX"; 
     private const string TRANSLATE_Y_TARGET = "Control.RenderTransform.CompositeTransform.TranslateY"; 
     private const string TRANSLATE_ROTATE_TARGET = "Control.RenderTransform.CompositeTransform.Rotation"; 


     public CustomControl() 
     { 
      this.RenderTransform = new CompositeTransform(); 

      TimeSpan duration = new TimeSpan(0,0,0,0,500); 
      double translateX = 10; 
      double translateY = 10; 
      double rotation = 40; 

      _compositeTransformExampleStoryBoard = BuildStoryboard(duration, translateX, translateY, rotation); 

      this.Loaded += CustomControl_Loaded; 
     } 

     void CustomControl_Loaded(object sender, RoutedEventArgs e) 
     { 
      _compositeTransformExampleStoryBoard.Begin(); 
     } 


     private Storyboard BuildStoryboard(TimeSpan animationDuration, double transistionValueX, double transistionValueY, double rotation) 
     { 
      Storyboard storyboard = new Storyboard(); 

      if (transistionValueX != 0) 
       CreateAnimation(storyboard, transistionValueX, animationDuration, TRANSLATE_X_TARGET); 

      if (transistionValueY != 0) 
       CreateAnimation(storyboard, transistionValueY, animationDuration, TRANSLATE_Y_TARGET); 

      if (rotation != 0) 
       CreateAnimation(storyboard, rotation, animationDuration, TRANSLATE_ROTATE_TARGET); 


      return storyboard; 
     } 

     private void CreateAnimation(Storyboard storyboard, double transistionValue, TimeSpan animationDuration, string targetProperty) 
     { 
      DoubleAnimation da = CreateDoubleAnimation(transistionValue, animationDuration); 
      storyboard.Children.Add(da); 
      Storyboard.SetTarget(da, this); 
      Storyboard.SetTargetProperty(da, targetProperty); 
     } 

     private DoubleAnimation CreateDoubleAnimation(double transistionValue, TimeSpan duration) 
     { 
      return new DoubleAnimation() 
      { 
       Duration = duration, 
       To = transistionValue 
      }; 
     } 

    } 
} 

相關問題