第一种是继承AnimationTimeline 抽象类

指定输出的时间段

 

public class GridLengthAnimation : AnimationTimeline
   {
       static GridLengthAnimation()
       {
           FromProperty = DependencyProperty.Register("From", typeof(GridLength), typeof(GridLengthAnimation));

           ToProperty = DependencyProperty.Register("To", typeof(GridLength), typeof(GridLengthAnimation));
       }

       public override Type TargetPropertyType
       {
           get
           {
               return typeof(GridLength);
           }
       }

       protected override System.Windows.Freezable CreateInstanceCore()
       {
           return new GridLengthAnimation();
       }

       public static readonly DependencyProperty FromProperty;

       public GridLength From
       {
           get
           {
               return (GridLength)GetValue(GridLengthAnimation.FromProperty);
           }
           set
           {
               SetValue(GridLengthAnimation.FromProperty, value);
           }
       }

       public static readonly DependencyProperty ToProperty;

       public GridLength To
       {
           get
           {
               return (GridLength)GetValue(GridLengthAnimation.ToProperty);
           }
           set
           {
               SetValue(GridLengthAnimation.ToProperty, value);
           }
       }

       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);
       }
   }

 

 

<Window x:Class="WpfTest.Window6"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window6" Height="300" Width="300">
    <Grid Background="Black" x:Name="mainGrid">
        <Grid.Resources>
            <Style TargetType="{x:Type Image}">
                <Setter Property="Stretch" Value="Fill" />
                <Setter Property="Margin" Value="2" />
            </Style>
        </Grid.Resources>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" Name="col0" />
            <ColumnDefinition Width="*" Name="col1" />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="*" Name="row0" />
            <RowDefinition Height="*" Name="row1" />
        </Grid.RowDefinitions>

        <Image MouseDown="image_MouseDown" Grid.Column="0" Grid.Row="0" Source="/Images/1.ico" />
        <Image MouseDown="image_MouseDown" Grid.Column="0" Grid.Row="1" Source="/Images/2.ico" />
        <Image MouseDown="image_MouseDown" Grid.Column="1" Grid.Row="0" Source="/Images/3.ico" />
        <Image MouseDown="image_MouseDown" Grid.Column="1" Grid.Row="1" Source="/Images/4.ico"/>

    </Grid>
</Window>

 

 

 /// <summary>
    /// Window6.xaml 的交互逻辑
    /// </summary>
    public partial class Window6 : Window
    {
        public Window6()
        {
            InitializeComponent();
        }

        bool bSingleImageMode = false;

        void image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Image image = sender as Image;
            if (image != null)
            {
                int col = Grid.GetColumn(image);
                int row = Grid.GetRow(image);

                for (int indexRow = 0; indexRow < mainGrid.RowDefinitions.Count; indexRow++)
                {
                    if (indexRow != row)
                    {
                        GridLengthAnimation gla = new GridLengthAnimation();
                        gla.From = new GridLength(bSingleImageMode ? 0 : 1, GridUnitType.Star);
                        gla.To = new GridLength(bSingleImageMode ? 1 : 0, GridUnitType.Star); ;
                        gla.Duration = new TimeSpan(0, 0, 2);
                        mainGrid.RowDefinitions[indexRow].BeginAnimation(RowDefinition.HeightProperty, gla);
                    }
                }

                for (int indexCol = 0; indexCol < mainGrid.ColumnDefinitions.Count; indexCol++)
                {
                    if (indexCol != col)
                    {
                        GridLengthAnimation gla = new GridLengthAnimation();
                        gla.From = new GridLength(bSingleImageMode ? 0 : 1, GridUnitType.Star);
                        gla.To = new GridLength(bSingleImageMode ? 1 : 0, GridUnitType.Star);
                        gla.Duration = new TimeSpan(0, 0, 2);
                        mainGrid.ColumnDefinitions[indexCol].BeginAnimation(ColumnDefinition.WidthProperty, gla);
                    }
                }
            }
            bSingleImageMode = !bSingleImageMode;
        }

    }

 

 

实现动态的变换布局

 

第二种是继承抽象类DoubleAnimationBase

 

 public class EaseMoveAnimation : DoubleAnimationBase
    {

        public static readonly DependencyProperty FromProperty = DependencyProperty.Register(
            "From", typeof(double?), typeof(EaseMoveAnimation), new PropertyMetadata(null));

        public static readonly DependencyProperty ToProperty = DependencyProperty.Register(
            "To", typeof(double?), typeof(EaseMoveAnimation), new PropertyMetadata(null));

        public static readonly DependencyProperty PowerProperty = DependencyProperty.Register(
            "Power", typeof(double?), typeof(EaseMoveAnimation), new PropertyMetadata(null));

        public double? From
        {
            get
            {
                return (double?)this.GetValue(EaseMoveAnimation.FromProperty);
            }
            set
            {
                this.SetValue(EaseMoveAnimation.FromProperty, value);
            }
        }

        public double? To
        {
            get
            {
                return (double?)this.GetValue(EaseMoveAnimation.ToProperty);
            }
            set
            {
                this.SetValue(EaseMoveAnimation.ToProperty, value);
            }
        }

        /// <summary>
        /// 幂指数,值越大,曲线上点的斜率越大,加速度越大,设置为5时效果较好
        /// </summary>
        public double? Power
        {
            get
            {
                return (double?)this.GetValue(EaseMoveAnimation.PowerProperty);
            }
            set
            {
                this.SetValue(EaseMoveAnimation.PowerProperty, value);
            }
        }

        protected override double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock)
        {
            double from = (this.From==null?defaultDestinationValue:(double)this.From);
            double to = (this.To==null?defaultOriginValue:(double)this.To);
            double delta = to - from;
            double power = this.Power == null ? 2 : (double)this.Power;

            //加速
            return delta * Math.Pow(animationClock.CurrentProgress.Value, power) + from;
            //return delta * Math.Pow(animationClock.CurrentProgress.Value, 1/power) + from;

           }
        protected override System.Windows.Freezable CreateInstanceCore()
        {
            return new EaseMoveAnimation();
        }
    }

 

 

/// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public partial class Window1 : System.Windows.Window
    {

        public Window1()
        {
            InitializeComponent();
            this.button1.Click += new RoutedEventHandler(button1_Click);
            this.button2.Click += new RoutedEventHandler(button2_Click);
        }

        void button2_Click(object sender, RoutedEventArgs e)
        {
            IniTest();
        }

        void button1_Click(object sender, RoutedEventArgs e)
        {
            IniTest();
        }

        private void IniTest()
        {

            EaseMoveAnimation animation1 = new EaseMoveAnimation();
            animation1.From = 0;
            animation1.To = 1000;
            animation1.Duration = TimeSpan.FromSeconds(2);
            animation1.Power = 5;
            this.button1.BeginAnimation(Canvas.LeftProperty, animation1);

            DoubleAnimation animation2 = new DoubleAnimation();
            animation2.From = animation1.From;
            animation2.To = animation1.To;
            animation2.Duration = animation1.Duration;
            this.button2.BeginAnimation(Canvas.LeftProperty, animation2);


        }

    }