ホームページ  >  記事  >  バックエンド開発  >  WPF で GridLengthAnimation をカスタマイズするチュートリアルの例

WPF で GridLengthAnimation をカスタマイズするチュートリアルの例

零下一度
零下一度オリジナル
2017-05-24 17:31:501613ブラウズ

この記事では、主に WPF で GridLengthAnimation をカスタマイズする関連情報を詳しく紹介します。興味のある方は参考にしてください。

要件

項目が表示されると、編集された右側など前面にもディテールを配置。

この要件は、グリッドを 2 つの列に分割し、2 つの列のを動的に調整することで実現できます。

Clomun の幅が であることはわかっていますが、デフォルトのアニメーションはこのように見えません。このような一人アニメーションを自分で実装する必要があります。

デザイン
アニメーションクラス図から見ることができます

要件から始めることができます

リスト内の項目を編集するときに、編集された詳細を右側などの前面に配置したい。

この要件は、グリッドを 2 つの列に分割し、2 つの列の幅を動的に調整することで達成できます。

Clomun の幅が GridLength であることはわかっていますが、デフォルトのアニメーションはこのようにはなりません。このような一人アニメーションを自分で実装する必要があります。

デザイン

AnimationTimeline がAnimation クラス図から継承し、その GetCurrentValue

public class GridLengthAnimation : AnimationTimeline
  {
    /// <summary>
    /// Returns the type of object to animate
    /// </summary>
    public override Type TargetPropertyType => typeof(GridLength);
 
    /// <summary>
    /// Creates an instance of the animation object
    /// </summary>
    /// <returns>Returns the instance of the GridLengthAnimation</returns>
    protected override System.Windows.Freezable CreateInstanceCore()
    {
      return new GridLengthAnimation();
    }
 
    /// <summary>
    /// Dependency property for the From property
    /// </summary>
    public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(GridLength),
      typeof(GridLengthAnimation));
 
    /// <summary>
    /// CLR Wrapper for the From depenendency property
    /// </summary>
    public GridLength From
    {
      get
      {
        return (GridLength)GetValue(GridLengthAnimation.FromProperty);
      }
      set
      {
        SetValue(GridLengthAnimation.FromProperty, value);
      }
    }
 
    /// <summary>
    /// Dependency property for the To property
    /// </summary>
    public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(GridLength),
      typeof(GridLengthAnimation));
 
    /// <summary>
    /// CLR Wrapper for the To property
    /// </summary>
    public GridLength To
    {
      get
      {
        return (GridLength)GetValue(GridLengthAnimation.ToProperty);
      }
      set
      {
        SetValue(GridLengthAnimation.ToProperty, value);
      }
    }
 
    /// <summary>
    /// Animates the grid let set
    /// </summary>
    /// <param name="defaultOriginValue">The original value to animate</param>
    /// <param name="defaultDestinationValue">The final value</param>
    /// <param name="animationClock">The animation clock (timer)</param>
    /// <returns>Returns the new grid length to set</returns>
    public override object GetCurrentValue(object defaultOriginValue,
      object defaultDestinationValue, AnimationClock animationClock)
    {
      double fromVal = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;
 
      double toVal = ((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;
 
      if (fromVal > toVal)
        return new GridLength((1 - animationClock.CurrentProgress.Value) * (fromVal - toVal) + toVal, GridUnitType.Star);
      else
        return new GridLength(animationClock.CurrentProgress.Value * (toVal - fromVal) + fromVal, GridUnitType.Star);
    }

を書き換えていることがわかります。上に示したように、デフォルトのアニメーションを模倣して From、To を実装し、そのプロパティを GridLength として定義します。アニメーションが実行されると、 From/To プロパティに従って関連付けられるように GetCurrentValue をオーバーライドします。

最適化

上記のコードを通じて、GridLength が変更されたときのアニメーションを実現できます。しかし、試してみたところ、アニメーションが少し直線的すぎることがわかりました。この時どうすればいいでしょうか?

EasingFunctionを導入することで実現可能です。 EasingFunction は実際には時間 t に関連する時間 関数 f(t) であることがわかります。時間関数の処理を通じて、アニメーションの遷移が非線形になります。


 /// <summary>
    /// The <see cref="EasingFunction" /> dependency property&#39;s name.
    /// </summary>
    public const string EasingFunctionPropertyName = "EasingFunction";
 
    /// <summary>
    /// Gets or sets the value of the <see cref="EasingFunction" />
    /// property. This is a dependency property.
    /// </summary>
    public IEasingFunction EasingFunction
    {
      get
      {
        return (IEasingFunction)GetValue(EasingFunctionProperty);
      }
      set
      {
        SetValue(EasingFunctionProperty, value);
      }
    }
 
    /// <summary>
    /// Identifies the <see cref="EasingFunction" /> dependency property.
    /// </summary>
    public static readonly DependencyProperty EasingFunctionProperty = DependencyProperty.Register(
      EasingFunctionPropertyName,
      typeof(IEasingFunction),
      typeof(GridLengthAnimation),
      new UIPropertyMetadata(null));

これに応じて、GetCurrentValue 関数を書き直す必要があります。


public override object GetCurrentValue(object defaultOriginValue,
      object defaultDestinationValue, AnimationClock animationClock)
    {
      double fromVal = ((GridLength)GetValue(FromProperty)).Value;
 
      double toVal = ((GridLength)GetValue(ToProperty)).Value;
 
      //check that from was set from the caller
      //if (fromVal == 1)
      //  //set the from as the actual value
      //  fromVal = ((GridLength)defaultDestinationValue).Value;
 
      double progress = animationClock.CurrentProgress.Value;
 
      IEasingFunction easingFunction = EasingFunction;
      if (easingFunction != null)
      {
        progress = easingFunction.Ease(progress);
      }
 
 
      if (fromVal > toVal)
        return new GridLength((1 - progress) * (fromVal - toVal) + toVal, GridUnitType.Star);
 
        return new GridLength(progress * (toVal - fromVal) + fromVal, GridUnitType.Star);
    }

を使用してください

 <anim:GridLengthAnimation Storyboard.TargetProperty="Width" From="0" To="*" Duration="0:0:0.5"/>

【関連推奨事項】

1. ASP.NETの無料ビデオチュートリアル

2. C# WinForm実装のショートカットキーカスタマイズ設定例、_PHPチュートリアル

3 。 WeChat パブリック アカウントのカスタム メニューの開発に関するサンプル チュートリアルを共有します

以上がWPF で GridLengthAnimation をカスタマイズするチュートリアルの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。