none
XAMLで書いたアニメーションを、データバインドで再生速度をリアルタイムに変えられないでしょうか? RRS feed

  • 質問

  • XAMLで、まずRectangleの中に、画像を置き、そのRectangleには、後から表示サイズをアニメーションで変化させるために

          <Rectangle.RenderTransform>
            <ScaleTransform x:Name="EngineScale"/>
          </Rectangle.RenderTransform>
    

    とScaleTransformを、名前をつけて置いています。

    これに対して、Windowが読み込まれた時に、下のXAMLでアニメーションを開始します。

            <BeginStoryboard>
              <Storyboard Name="EngineAnimation">
                <DoubleAnimation Storyboard.TargetName="EngineScale" Storyboard.TargetProperty="ScaleX"
                 RepeatBehavior="Forever" From="1" To="2" Duration="0:0:1" AutoReverse="True"/>
                <DoubleAnimation Storyboard.TargetName="EngineScale" Storyboard.TargetProperty="ScaleY" 
                 RepeatBehavior="Forever" From="1" To="2" Duration="0:0:1" AutoReverse="True"/>
              </Storyboard>
            </BeginStoryboard>
    


    単純に、大きくなったり小さくなったりを永遠に繰り返すだけの単純なアニメーションです。

    ここまでは何の問題もなく動いています。

    問題は、このアニメーションの再生速度(大きくなったり小さくなったり)を、後から、ユーザーの操作によってリアルタイムに変更する方法が、うまくわからずに困っています。

    Storyboardの中には、ScaleX用とScaleY用の2つのDoubleAnimationがありますが、それぞれに、

    SpeedRatio="{Binding ○○}"
    

    などとして、直接SpeedRatioにデータバインドを試してみましたが、これでは全く速度が変わりませんでした。

    次に、SetSpeedRatioというメソッドがあることを知り、コードビハインドになってしまいますが、

    private void slider1_ValueChanged(object sender, RoutedEventArgs e)
    {
      EngineAnimation.SetSpeedRatio(this, slider1.Value);
    }
    

    などいうものを実験で入れてみましたが、スライダーを動かしても、やはり全く再生速度が変化しません。

    再生開始前にXAMLの中でSpeedRatio=○○としてやった場合は、ちゃんと再生速度が変化するのですが、一度再生が始まった後は、今のところ変えることができません。再生し続けながら速度だけを変えたいのですが、うまく行きません。

    何かよい方法はないでしょうか? よろしくお願いします。


    なお、これらのXAMLおよびコードビハインドは、ユーザーコントロールとして作っています。

    2011年12月11日 2:08

回答

すべての返信

  • SetSpeedRatio メソッド (Double)

    の解説によると、明示的に Storyboard.Begin したものじゃないと使えないそうです。

    2011年12月11日 4:32
  • 一度再生が始まった後は、今のところ変えることができません。再生し続けながら速度だけを変えたいのですが、うまく行きません。

    何かよい方法はないでしょうか? よろしくお願いします。

    一旦Storyboardを開始した場合は、

    SetStoryboardSpeedRatio

    を使います。


    Need translation help? I translate from English to Japanese and vice versa. Please feel free to contact me for your translation needs. 日英・英日翻訳依頼を受け付けています。 お気軽にご相談下さい。(Ldiary.com)
    2011年12月11日 22:22
  • レスありがとうございます。

    一応、

     

        <EventTrigger RoutedEvent="Button.Click" SourceName="button1">
          <SetStoryboardSpeedRatio BeginStoryboardName="EngineAnimation" SpeedRatio="5"/>
        </EventTrigger>
    
    などとしてやるとボタンを押せばアニメーションを再生し続けたまま速度が変わりましたし、同様に、一行目を

     

        <EventTrigger RoutedEvent="Slider.ValueChanged" SourceName="slider1">
    

    と、変えてやれば、スライダーを変更したタイミングでも再生し続けつつ速度が変えられるようです。

    ただし、この方法だと、SpeedRatio="○○"と、XAMLの中で直接打っている速度へ固定で変化するだけで、再生後の速度を何倍速にするかというのが固定になってしまっていて、変化させることができません。

    スライダーで値を変化させるのと同期してなめらかに、1.0倍、1.1倍、1.2倍…という感じで、無段階に速度を変化させたいのですが、今のところ、SpeedRatio="○○"と決め打ちした固定の速度にしか変化させられません。

    SetStoryboardSpeedRatioのSpeedRatioプロパティを、何とか、データバインドなどで変更させることができれば、これで望む動作をさせられそうなのですが、なんとか方法はないでしょうか?


    • 編集済み minami259 2011年12月12日 5:35
    2011年12月12日 5:33
  • SetStoryboardSpeedRatioのSpeedRatioプロパティを、何とか、データバインドなどで変更させることができれば、これで望む動作をさせられそうなのですが、なんとか方法はないでしょうか?

    一旦開始したアニメーションに対して、データバインドなどは無力です。詳しい内容は以下のスレッドをご参考下さい。

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/4ae9aaad-a75b-4563-a919-d426b544da85/

    こちらでは、最終手段としてCurrentTimeInvalidatedを活用しています。


    Need translation help? I translate from English to Japanese and vice versa. Please feel free to contact me for your translation needs. 日英・英日翻訳依頼を受け付けています。 お気軽にご相談下さい。(Ldiary.com)
    • 編集済み Ldiary 2011年12月12日 6:53
    2011年12月12日 6:52
  • SetStoryboardSpeedRatioのSpeedRatioプロパティは依存関係プロパティではないのでバインドできません。以下が参考になりそうです。

    Dynamically Change a Rotation Animation in WPF
    http://stackoverflow.com/questions/692634/dynamically-change-a-rotation-animation-in-wpf

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク minami259 2011年12月12日 12:48
    • 回答としてマークされていない minami259 2011年12月12日 12:49
    • 回答としてマーク minami259 2011年12月12日 12:50
    2011年12月12日 8:38
    モデレータ
  • trapimiyaさんのリンク先のコードを参考にしたところ、うまく行きました。

    回答いただいたみなさん、ありがとうございました。

    2011年12月12日 12:50