2009-03-28 17 views
9

DoubleAnimationを使用して、RotationTransformのAngleプロパティをアニメートしています。毎秒数回、外部データに応答して回転速度を変更して、回転速度が時間の経過とともにスピードアップ(スムーズに)するようにする必要があります。 WPFの回転アニメーションを動的に変更

  • がそれにDoubleAnimationにレートを変更し

    • グラブ外部データから新しい値:私は現在、期間Xを0.0から360.0に永遠に繰り返されるDoubleAnimation、毎秒その後、数回使用してこれをやっています角度プロパティに値
    • 再適用DoubleAnimation再び

    注:私は、私はを変更しなければならなかったとアニメーションのプロパティから「現在の角度」と「現在の角度+ 360」にすることを見つけました - 私にとって幸運なことに、RotationTransformはアングルに問題はありません> 360度 - ゼロ角度からの回転を再び開始しないようにします。

    私の質問です:これは妥当ですか?そうは思われません。回転変換のAngleプロパティに新しいDoubleAnimationsを継続的に適用することは間違っています。つまり、WPFで回転をアニメーション化するようなことです。I自分自身で回転速度をアニメーションしています。

    良い方法がありますか?

  • 答えて

    8

    ストーリーボードには、期間に対する乗数であるSpeedRatio設定があります。ただし、これは依存関係プロパティではないため、バインドすることはできません。

    これを回避するには、ストーリーボードでSetSpeedRatio関数を使用します。これは、ストーリーボードがコードで開始されている場合(エラーが発生した場合)にのみ機能します。

    以下のコードは、回転矩形のアニメーションのスピードに影響するオブジェクトのイベントを発生させる方法の完全な例です。テキストボックスとデータバインディングの目的は、バックグラウンドオブジェクトを更新することです。ボタンは、テキストボックスがフォーカスを失い、オブジェクトを更新するようなものです。

    その後
    <Window x:Class="WpfApplication1.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="Window1" Height="300" Width="300"> 
        <StackPanel> 
         <Rectangle Margin="50" Width="50" Height="50" Fill="Red" x:Name="rc"> 
         <Rectangle.RenderTransform> 
          <RotateTransform x:Name="TransRotate" 
              CenterX="25" CenterY="25" Angle="0" /> 
         </Rectangle.RenderTransform> 
         <Rectangle.Resources> 
          <Storyboard x:Key="spin"> 
          <DoubleAnimation x:Name="da" 
              Storyboard.TargetName="TransRotate" 
              Storyboard.TargetProperty="Angle" 
              By="360" 
              Duration="0:0:10" 
              AutoReverse="False" 
              RepeatBehavior="Forever" /> 
          </Storyboard> 
         </Rectangle.Resources> 
         </Rectangle> 
         <TextBox Text="{Binding Speed}" /> 
         <Button>Update Speed</Button> 
        </StackPanel> 
    </Window> 
    

    C#コード

    { 
        public Window1() 
        { 
         InitializeComponent(); 
    
         //create new object 
         BackgroundObject bo = new BackgroundObject(); 
    
         //binding only needed for the text box to change speed value 
         this.DataContext = bo; 
    
         //Hook up event 
         bo.SpeedChanged += bo_SpeedChanged; 
    
         //Needed to prevent an error 
         Storyboard sb = (Storyboard)rc.FindResource("spin"); 
         sb.Begin(); 
        } 
    
        //Change Speed 
        public void bo_SpeedChanged( object sender, int newSpeed) 
        { 
         Storyboard sb = (Storyboard)rc.FindResource("spin"); 
         sb.SetSpeedRatio(newSpeed); 
        } 
    } 
    
    public delegate void SpeedChangedEventHandler(object sender, int newSpeed); 
    
    public class BackgroundObject 
    { 
        public BackgroundObject() 
        { 
         _speed = 10; 
        } 
    
        public event SpeedChangedEventHandler SpeedChanged; 
    
        private int _speed; 
        public int Speed 
        { 
         get { return _speed; } 
         set { _speed = value; SpeedChanged(this,value); } 
        } 
    } 
    

    私はあなたの利用状況に適応することができます確信しています。

    +0

    これは非常に高く評価されます。 – Bill

    +1

    ありがとう、私はそれを使用することができます。面白いことに、私たちはメソッド呼び出し(SetSpeedRatio)を行う必要があります。つまり、Xamlやすべてで、別のアニメーションで速度比の変更をアニメートできません。これは、効果を得るために常に新しいアニメーションを適用するよりはるかに正しいように見えます。 ありがとうございます。 – Bill

    +0

    この回答は私たちのケースでは最も役に立ちましたが、それがうまくいかない重要な違いが1つあります。少なくともWinRTのWPFで。 SetSpeedRatio()メソッドは何もしませんでしたので、SpeedRatioプロパティに変更しました。それはトリックでした。 –