Exemple de tutoriel de personnalisation de GridLengthAnimation dans WPF

零下一度
Libérer: 2017-05-24 17:31:50
original
1576 Les gens l'ont consulté

Cet article présente principalement les informations pertinentes sur la personnalisation de GridLengthAnimation dans WPF en détail. Il a une certaine valeur de référence. Les amis intéressés peuvent se référer aux

Exigences

Lorsque nous modifions un élément dans une liste, nous souhaitons placer les détails modifiés devant, par exemple sur le côté droit.

Cette exigence peut être satisfaite en divisant une grille en deux colonnes et en ajustant dynamiquement la

Largeur des deux colonnes.

Nous savons que la largeur de Clomun est de , mais l'animation par défaut ne ressemble pas à ceci. Nous devons mettre en œuvre nous-mêmes une telle animation par une seule personne.

Conception
Nous voyons à partir du diagramme de classe d'animation

Nous pouvons partir des exigences

Lorsque nous modifions un élément dans une liste, nous souhaitons placer les détails modifiés devant, par exemple sur le côté droit.

Cette exigence peut être satisfaite en divisant une grille en deux colonnes et en ajustant dynamiquement la largeur des deux colonnes.

Nous savons que la largeur de Clomun est une GridLength, mais l'animation par défaut ne ressemble pas à ceci. Nous devons mettre en œuvre nous-mêmes une telle animation par une seule personne.

Design

Nous voyons l'héritage AnimationTimeline du diagramme de classe Animation et réécrivons son 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);
    }
Copier après la connexion
Comme indiqué ci-dessus, nous imitons la valeur par défaut l'animation implémente From et To, et son

attribut est défini comme GridLength. Lorsque l'animation est exécutée, nous réécrivons GetCurrentValue pour l'associer en fonction de l'attribut From/To.

Optimisation

Grâce au code ci-dessus, nous pouvons réaliser une animation lorsque GridLength change. Cependant, après l'avoir testé, nous avons constaté que l'animation était un peu trop linéaire. Que dois-je faire à ce moment-là ?

peut être réalisé en introduisant EasingFunction. Nous savons que EasingFunction est en fait une fonction temporelle

f(t) liée au temps t Grâce au traitement de la fonction temporelle, nous rendons la transition d'animation moins linéaire.


 /// <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));
Copier après la connexion
En conséquence, la fonction GetCurrentValue doit être réécrite.


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);
    }
Copier après la connexion

Utilisez

 <anim:GridLengthAnimation Storyboard.TargetProperty="Width" From="0" To="*" Duration="0:0:0.5"/>
Copier après la connexion
【Recommandations associées】

1. Tutoriel vidéo gratuit .NET

2.

Exemple de personnalisation des touches de raccourci dans C# WinForm, tutoriel _PHP

3.

Partager le compte officiel WeChat Développer la personnalisation. tutoriel exemple de menu

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
wpf
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!