2016-07-11 2 views
0

現在、フライアウトモードを備えた何らかのメニューに取り組んでいます。マウスオーバーするまで、コンパクトモード(〜60px幅のみ)のままです。あなたはコントロールの幅を直接アニメーション化することはできませんし、固定サイズ(これは私が望むものではありません)を設定するので、テーマは非常に難しいです。ダイナミックにコントロールサイズのアニメートを動的に変更する

私の目標は、その子と最大値に基づいて動的なサイズを持つことができるコントロールを持つことです。その親に利用可能なスペース。

私の理論:サイズが変更されると、使用可能な最大スペース(使用されるよりもはるかに大きい)を測定する測定が呼び出されます。次のステップは、に配置することです。 ArrangeOverride()が呼び出され、パラメータarrangeBoundsが希望のサイズに相当します。

今、私は、この値をキャッシュし、それがActualSizeプロパティに違う場合、私はarrangeBounds.WidthActualSizeからアニメーションを開始。テストプロジェクトを開始するとき

protected override Size ArrangeOverride(Size arrangeBounds) 
{ 
    if (Math.Abs(WidthWrapper) < 0.01) 
     WidthWrapper = arrangeBounds.Width; 

    if (Math.Abs(arrangeBounds.Width - ActualWidth) > 0.01) 
    { 
     if (_started & (Math.Abs(arrangeBounds.Width - _cache) < 0.01)) 
      return base.ArrangeOverride(new Size(WidthWrapper, arrangeBounds.Height)); 
     if (Math.Abs(arrangeBounds.Width - WidthWrapper) < 0.01) 
      return base.ArrangeOverride(new Size(WidthWrapper, arrangeBounds.Height)); 

     if (_started & !_isExpanding) 
     { 
      Console.WriteLine("Re-Animate"); 
      // Change value 
      if (_cache < arrangeBounds.Width) 
       _isExpanding = true; 
      _cache = arrangeBounds.Width; 

      _board.Stop(this); 
      _board.Children.Clear(); 
      _anim = new DoubleAnimation(WidthWrapper, arrangeBounds.Width, 
       new Duration(TimeSpan.FromSeconds(0.8))) 
      { 
       EasingFunction = new QuadraticEase() {EasingMode = EasingMode.EaseInOut} 
      }; 
      _board.Children.Add(_anim); 
      Storyboard.SetTarget(_anim, this); 
      Storyboard.SetTargetProperty(_anim, new PropertyPath(WidthWrapperProperty)); 
      _board.Begin(this); 

      return base.ArrangeOverride(new Size(WidthWrapper, arrangeBounds.Height)); 
     } 

     if (!_started) 
     { 
      if (_cache < arrangeBounds.Width) 
       _isExpanding = true; 
      _cache = arrangeBounds.Width; 
      _anim = new DoubleAnimation(WidthWrapper, arrangeBounds.Width, 
       new Duration(TimeSpan.FromSeconds(1.5))) 
      { 
       EasingFunction = new QuadraticEase() {EasingMode = EasingMode.EaseInOut} 
      }; 
      _board.Children.Add(_anim); 
      Storyboard.SetTarget(_anim, this); 
      Storyboard.SetTargetProperty(_anim, new PropertyPath(WidthWrapperProperty)); 
      _board.Begin(this, true); 
      _started = true; 
     } 
    } 

    Size animatedSize = new Size(WidthWrapper, arrangeBounds.Height); 
    return base.ArrangeOverride(animatedSize); 
} 

、メニューがほとんどで開始します: - 方法自体は、これまでのところ、私はこれを持っている(WidthWrapperは、単にしたDependencyPropertyであり、それは部分的に取り組んでいる)return base.ArrangeOverride(new Size(WidthWrapper, arrangeBounds.Height));

のようなサイズのオブジェクトを返しませんフルサイズで、右側から「フェードイン」している部分が見えます。これは本当にクールです。今問題は、コンパクトモードに切り替えるとアニメーションがないことです。それはすぐに〜61px幅になります。私がそれを上に置くと、あなたはそれが拡大するのを見るが、ちらつきで、それは以前のサイズに無作為にジャンプする。

明らかに、このアプローチを使用することによってコントロールが誤って配置されるという問題があります。このアニメーションを行うときに、右から少しずれるようです。したがって、マウスオーバーはもはや検出されず、コンパクトサイズにアニメーション化しようとします。これは、アニメーションが完了するまで頻繁に起こり、最終的にフルサイズに達します(アニメーションがまったくない場合)。

親との配置問題のようです。私はここにGIFを含めるので、あなたは私が何を意味するか見ることができます。

Animation

PS:(それは部分的に動作し、非常に素敵になりますが)私は、「フライアウト」-modeを無効にし、それでも圧縮する法線からの切り替えちょっとそれは問題だしました。

これを解決する方法は、どのようなちらつきなどの問題もなくスムーズに展開できるようにする方法ですか?プロフェッショナルなUIライブラリには、固定解除時に迅速にフェードアウトするドッキングウィンドウがあります。私はこの種の効果を何とか私のメニューに適用したいと思っています。私はこれが可能だと私はすでに近づいていると仮定していますが、明らかにWPFはちょっとしたトリッキーなことなしにサポートしていません。

+1

XAMLではなく、このコードビハインドを行う特別な理由はありますか?あなたのアニメーションは単純なTranslateTransformのように見えます – lokusking

+0

@ lokusking Clintの答えに対する私のコメントを参照してください。 – SharpShade

答えて

2

は基本的にあなたが開閉状態を記述することをお勧めします、と使用は状態間の動きをアニメーション化する変換Visual State ManagerTranslate Transform

を見てみましょう。

+0

これは、コントロールの望ましいサイズに依存しませんか?私は翻訳が固定値であることを意味しますね。コントロールのサイズがコンパクトであるかノーマルモードであるかは言えません。これは柔軟でなければなりません。 – SharpShade

+1

AFAIK、 'From'および' To'はDoubleAnimationでバインド可能です。そして、TranslateTransformのXも結合可能でなければなりません。 – lokusking

+0

@SharpShadeそれは、コントロールのサイズに対して言及されたlokuskingの単なる二重アニメーションです。 – Clint

関連する問題