2011-01-05 8 views
6

私は私を殺している問題があります。以下は高さの設定をアニメーションした後に、このプロパティが直接動作を停止します

private void _resizeButton_Click(object sender, RoutedEventArgs e) 
{ 
    button.Height += 10; 
} 

private void _animateButton_Click(object sender, RoutedEventArgs e) 
{ 
    Storyboard storyboard = new Storyboard(); 

    DoubleAnimation animation = new DoubleAnimation(button.Height + 10, new Duration(new TimeSpan(0, 0, 0, 1))); 
    storyboard.Children.Add(animation); 

    Storyboard.SetTargetName(animation, button.Name); 
    Storyboard.SetTargetProperty(animation, new PropertyPath(HeightProperty)); 

    storyboard.Begin(_grid); 
} 

アプリケーションが_resizeButtonはボタンがすぐに大きく左に押した後、この

alt text

のように見えるの後ろ

<Grid Name="_grid"> 
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="36,33,0,0" Name="button" VerticalAlignment="Top" Width="75" /> 
    <Button Content="Enlarge through animation" Height="23" Margin="172,33,24,0" Name="_animateButton" VerticalAlignment="Top" Click="_animateButton_Click" /> 
    <Button Content="Enlarge through simple heigh changing" Height="23" Margin="172,62,24,0" Name="_resizeButton" VerticalAlignment="Top" Click="_resizeButton_Click" /> 
</Grid> 

とコードで簡単な例です。次に、_animateButtonを押しています - 左ボタンがゆっくりと拡大しています。その後、私は_resizeButtonをもう一度押して、何も起こっていません。何故ですか?

私は同じことがTopプロパティ

答えて

15

動作を理解するには、WPFのプロパティシステムでアニメーションがどのように動作するかを知っておく必要があります。アニメーションは、時間の経過とともにプロパティを異なる値に設定すると機能しません。彼らは一時的に '基本'の値よりも優先されるプロパティの実効値を提供することによって動作します。これは微妙な違いですが、ここであなたが邪魔になる原因です。

最初にアニメーションシステムに遭遇したとき、ほとんどの人は、プロパティに対して「セット」アクセサを繰り返し呼び出すことによって動作すると想像します。しかし、アニメーションを開始する前にそのようにプロパティを設定すると、設定した元の値がそのまま残ります。ゲッターはアニメーションシステムから供給された値を返すだけで、 'local'値を返すことになります。実際には、アニメーションの実行中にプロパティを設定することで 'ローカル'値を変更することもできますが、アニメーションが停止するまでローカル値は表示されません。

実際、プロパティシステムではこのようなことがたくさんあります。これは単なるアニメーションではありません。このhelp topicには、プロパティの値が得られる11の異なる場所がリストされています。アニメーションは2番目に高い優先順位です。次の優先順位は、 'set'アクセサ(またはXamlの属性)を介して通常の方法で設定されたプロパティですが、テンプレート、スタイル、およびトリガは、すべてローカルプロパティ値がない場合に他のソースを提供します。

WPFのアニメーションシステムには、 '基本'値の概念があり、基本的には現在のアニメーション化された値の次に優先度の高い値です。ローカル値を持っていれば、その値はベース値になりますが、そうでない場合は、その値が、その記事にリストされている他のソースから来ます。

あなたがしようとしているようなことをする簡単な方法はないということです。私はあなたが望むものは、アニメーションが完了するまで実行され、ローカルの値を何か他のものに設定するまで、プロパティが最終的なアニメーション値を保持することだと思います。

アニメーションが完了すると停止するように指示すると、実効値は元の値に戻ります。 (コメントで言うように、アニメーションが完了した後に収縮します)そして、完了したらアニメーションを終了するように指示すると(デフォルトの動作)、アニメーションはローカル値よりも優先順位が高い値を永遠に提供しますこれは、手動でボタンのサイズ変更が機能しなくなったのを見る理由です。だからどちらのオプションもあなたが望むことをしません。

これに対処するには2通りの方法があります。 @responderNS5は、アニメーションの完了を処理し、ローカル値を変更してアニメーションの最終値を反映させた後、アニメーションを停止します。 (これは、これをプロパティの降格の一種と考えることができます - 優先度は高いが一時的なアニメーション提供のプロパティ値からわずかに低い優先度ですが、より永続的なローカル値に変換します)。コード少し:私はここに変更したことのコードは、もはやアニメーションシステムが終わった場所を推測しようとしたということではありません

private void myDoubleAnimation_Completed(object sender, EventArgs e) 
{ 
    // Animation complete, but holding, so Height will currently return 
    // return the final animated value. 
    double finalHeight = button.Height; 

    // Remove the animation. 
    button.BeginAnimation(Button.HeightProperty, null); 

    // Modify the local value to be the same as the final animated value. 
    button.Height = finalHeight; 
} 

- これは単なるアニメーションシステムはにプロパティを設定していたどのような値読み込み、ということになり新しいローカル値私はCompletedハンドラ内の+= 10にそれを好んでいます。これは、私にはロジックが少し壊れやすいように感じます。

それに対処するために、他の方法は、あなたがプロパティを更新しようとした時点でアニメーションを削除することです:

これがあっても動作しますので、これは、少しより堅牢な私には思えますリサイズボタンをクリックするまでにアニメーションが終了していませんでした。

3

をアニメーション化されたときにことに気づいたあなたはDoubleAnimationStop代わりのHoldへのFillBehaviorを設定する必要があります。この記事を参照してください:あなたはそれを指摘したように

+0

あなたの答えはありがたいですが、animation.FillBehavior = FillBehaviorを設定していただきありがとうございます。縮小率を最後の高さの値に戻してください。私は何か間違っているのですか? – bizon

+0

ありがとうございました!!!時間を節約しました! – Rocklan

3

リックの答えは動作しません。あなたの場合、アニメーションプロパティのアニメーション(ボタンの高さ)をnullに設定して、このプロパティをさらに変更する必要があります。

http://msdn.microsoft.com/en-us/library/aa970493.aspx

private void _animateButton_Click(object sender, RoutedEventArgs e) 
    { 
     DoubleAnimation animation = new DoubleAnimation(); 
     animation.By = 10; 
     animation.Duration = new Duration(TimeSpan.FromSeconds(1)); 
     animation.Completed += new EventHandler(myDoubleAnimation_Completed); 
     button.BeginAnimation(Button.HeightProperty, animation); 
    } 

    private void myDoubleAnimation_Completed(object sender, EventArgs e) 
    { 
     button.BeginAnimation(Button.HeightProperty, null); 
     button.Height += 10; 
    } 

変更上記に示したものに、あなたの_animateButton_Clickハンドラ。また、アニメーションが完了したときに、「アニメーション」への参照を削除できるように、2番目のイベントハンドラを追加します。myDoubleAnimation_Completedの2番目のステートメントは、アニメーション参照が削除されると、アニメーション化されていない値が表示されるためです。

+0

パーフェクト..これには答えがない他の投稿があります。あなたの答えにリンクを貼ります – Sayka

関連する問題