Подтвердить что ты не робот

Как анимировать свойство Margin в WPF

Я хочу переместить анимацию объекта прямоугольника, чтобы переместить его по оси x. Я новичок в анимации WPF, начал со следующего:

<Storyboard x:Key="MoveMe">
    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                   Storyboard.TargetName="GroupTileSecond"
                                   Storyboard.TargetProperty="(**Margin.Left**)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="**134, 70,0,0**" />
        <SplineDoubleKeyFrame KeyTime="00:00:03" Value="**50, 70,0,0**" />
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Очевидно, выяснилось, что я не могу использовать Margin.Left как Storyboard.TargetProperty или использовать 134,70,0,0 в свойстве Value.

Итак, как мне перемещать объект в XAML WPF.

4b9b3361

Ответ 1

Margin свойство можно анимировать с помощью ThicknessAnimation

<Storyboard >
     <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" BeginTime="00:00:00">
        <SplineThicknessKeyFrame KeyTime="00:00:00" Value="134, 70,0,0" />
        <SplineThicknessKeyFrame KeyTime="00:00:03" Value="50, 70,0,0" />
     </ThicknessAnimationUsingKeyFrames>
</Storyboard>

Ответ 2

На самом деле, вы можете делать то, что хотите, точно так же, как хотите, используя RenderTransform, смешанный с некоторыми DoubleAnimation, и даже добавьте к нему дополнительные возможности, например:

<Grid x:Name="TheObject" Opacity="0">
      <Grid.RenderTransform>
            <TranslateTransform x:Name="MoveMeBaby" X="50" />
      </Grid.RenderTransform>
      <Grid.Triggers>
            <EventTrigger RoutedEvent="Grid.Loaded">
                  <BeginStoryboard>
                         <Storyboard>
                              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MoveMeBaby" Storyboard.TargetProperty="X">
                                   <SplineDoubleKeyFrame KeyTime="0:0:1.25" Value="0" />
                              </DoubleAnimationUsingKeyFrames>
                              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TheObject" Storyboard.TargetProperty="Opacity">
                                   <SplineDoubleKeyFrame KeyTime="0:0:1.55" Value="1" />
                              </DoubleAnimationUsingKeyFrames>
                         </Storyboard>
                  </BeginStoryboard>
            </EventTrigger>
      </Grid.Triggers>

Переместит этот объект 50px по оси X и даже увянет его, пока он это сделает. Сделайте снимок и играйте со значениями свойства X и KeyTime, чтобы получить то, что вы хотите. Надеюсь, это помогает, приветствует.

Ответ 3

Вы не можете анимировать Margin.Left(потому что Left не является свойством зависимостей), но вы можете анимировать Margin. Используйте ObjectAnimationUsingKeyFrames:

<Storyboard x:Key="MoveMe">
    <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" 
            Storyboard.TargetName="GroupTileSecond" 
            Storyboard.TargetProperty="Margin">
        <DiscreteObjectKeyFrame KeyTime="00:00:00">
            <DiscreteObjectKeyFrame.Value>
                <Thickness>134,70,0,0</Thickness>
            </DiscreteObjectKeyFrame.Value>
        </DiscreteObjectKeyFrame>
        <DiscreteObjectKeyFrame KeyTime="00:00:03">
            <DiscreteObjectKeyFrame.Value>
                <Thickness>50,70,0,0</Thickness>
            </DiscreteObjectKeyFrame.Value>
        </DiscreteObjectKeyFrame>
    </ObjectAnimationUsingKeyFrames>
</Storyboard>

Есть несколько альтернатив, которые позволяют использовать DoubleAnimation, а не ключевые фреймы:

  • Поместите свою цель внутри холста и анимируйте ее позицию x с помощью Canvas.Left.
  • Примените TranslateTransform к своей цели и анимируйте ее положение x, используя TranslateTransform.X.

Ответ 4

В качестве альтернативного ответа @McGarnagle вы можете использовать анимацию для свойств HorizontalAlignment и VerticalAlignment.

Пример:

<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GroupTileSecond" 
                               Storyboard.TargetProperty="HorizontalAlignment">

    <DiscreteObjectKeyFrame KeyTime="0:0:0">
        <DiscreteObjectKeyFrame.Value>
            <HorizontalAlignment>Center</HorizontalAlignment>
        </DiscreteObjectKeyFrame.Value>
    </DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>

Ответ 5

Я только что создал анимацию. код ниже

using System;
using System.Windows;
using System.Windows.Media.Animation;

namespace ImagesSwitcher
{
    class MarginAnimation : AnimationTimeline
    {
        protected override Freezable CreateInstanceCore()
        {
            return new MarginAnimation();
        }

    public override Type TargetPropertyType => typeof(Thickness);

    private double GetContrast(double dTo,double dFrom,double process)
    {
        if (dTo < dFrom)
        {
            return dTo + (1 - process) * (dFrom - dTo);
        }

        return dFrom + (dTo - dFrom) * process;
    }

    public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
    {
        if (!From.HasValue || !To.HasValue || animationClock.CurrentProgress == null) return null;
        var progress = animationClock.CurrentProgress.Value;

        if (progress.Equals(0)) return null;

        if (progress.Equals(1)) return To.Value; 

        var fromValue = From.Value;
        var toValue = To.Value;

        var l = GetContrast(toValue.Left ,fromValue.Left, progress);
        var t = GetContrast(toValue.Top, fromValue.Top, progress);
        var r = GetContrast(toValue.Right, fromValue.Right, progress);
        var b = GetContrast(toValue.Bottom, fromValue.Bottom, progress);

        return new Thickness(l,t,r,b);
    }

    public Thickness? To
    {
        set => SetValue(ToProperty, value);
        get => (Thickness)GetValue(ToProperty);
    }
    public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(Thickness), typeof(MarginAnimation), new PropertyMetadata(null));

    public Thickness? From
    {
        set => SetValue(FromProperty, value);
        get => (Thickness)GetValue(FromProperty);
    }
    public static DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(Thickness), typeof(MarginAnimation), new PropertyMetadata(null));

}

}