微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Silverlight中为Margin添加动画

因为在Silverlight中没有ThicknessAnimation,所以为Margin添加动画有点麻烦:

1. 使用ObjectAnimationUsingKeyFrames来做,这个就是通过计算要显示的每一帧内容来设置动画,可能看起来不是那么平滑,如果需要平滑的话,那样就需要写代码来动态生成动画效果,看起来会平滑很多。

使用XAML来进行描述就是这样:

<Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDeFinitions>
            <RowDeFinition Height="*"/>
            <RowDeFinition Height="150"/>
        </Grid.RowDeFinitions>
        <Grid.Resources>
            <Storyboard x:Name="sb">
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin"
                                   Storyboard.TargetName="bdTest">
                    <discreteObjectKeyFrame KeyTime="0" Value="0"/>
                    <discreteObjectKeyFrame KeyTime="0:0:0.5">
                        <discreteObjectKeyFrame.Value>
                            <Thickness>3,7,5,9</Thickness>
                        </discreteObjectKeyFrame.Value>
                    </discreteObjectKeyFrame>
                    <discreteObjectKeyFrame KeyTime="0:0:0.6">
                        <discreteObjectKeyFrame.Value>
                            <Thickness>4,8,6,10</Thickness>
                        </discreteObjectKeyFrame.Value>
                    </discreteObjectKeyFrame>
                    <discreteObjectKeyFrame KeyTime="0:0:0.7">
                        <discreteObjectKeyFrame.Value>
                            <Thickness>40,80,60,100</Thickness>
                        </discreteObjectKeyFrame.Value>
                    </discreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </Grid.Resources>
        <Border x:Name="bdTest" Grid.Row="0" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Background="Red" />
        <Button Content="Button" HorizontalAlignment="Left" Grid.Row="1" VerticalAlignment="Top" Width="75" Click="Button_Click_1" />
        
    </Grid>

2. 另一种方式请参见 Code Project:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ThicknessAnimation
{
	public class ThicknessWrapper : FrameworkElement
	{

		public FrameworkElement Target
		{
			get
			{
				return (FrameworkElement)GetValue(TargetProperty);
			}
			set
			{
				SetValue(TargetProperty,value);
			}
		}

		// Using a DependencyProperty as the backing store for Target.  This enables animation,styling,binding,etc...
		public static readonly DependencyProperty TargetProperty =
			DependencyProperty.Register("Target",typeof(FrameworkElement),typeof(ThicknessWrapper),new PropertyMetadata(null,OnTargetChanged));


		static void OnTargetChanged(DependencyObject source,DependencyPropertyChangedEventArgs args)
		{
			ThicknessWrapper sender = (ThicknessWrapper)source;
			sender.UpdateMargin();
		}




		public String PropertyName
		{
			get
			{
				return (String)GetValue(PropertyNameProperty);
			}
			set
			{
				SetValue(PropertyNameProperty,value);
			}
		}

		// Using a DependencyProperty as the backing store for PropertyName.  This enables animation,etc...
		public static readonly DependencyProperty PropertyNameProperty =
			DependencyProperty.Register("PropertyName",typeof(String),new PropertyMetadata("Margin"));



		public Side Side
		{
			get
			{
				return (Side)GetValue(SideProperty);
			}
			set
			{
				SetValue(SideProperty,value);
			}
		}

		// Using a DependencyProperty as the backing store for Side.  This enables animation,etc...
		public static readonly DependencyProperty SideProperty =
			DependencyProperty.Register("Side",typeof(Side),new PropertyMetadata(Side.Left,OnSideChanged));


		static void OnSideChanged(DependencyObject source,DependencyPropertyChangedEventArgs args)
		{
			ThicknessWrapper sender = (ThicknessWrapper)source;
			sender.UpdateMargin();
		}


		public double Value
		{
			get
			{
				return (double)GetValue(ValueProperty);
			}
			set
			{
				SetValue(ValueProperty,value);
			}
		}

		// Using a DependencyProperty as the backing store for Value.  This enables animation,etc...
		public static readonly DependencyProperty ValueProperty =
			DependencyProperty.Register("Value",typeof(double),new PropertyMetadata(0.0,OnValueChanged));


		static void OnValueChanged(DependencyObject source,DependencyPropertyChangedEventArgs args)
		{
			ThicknessWrapper sender = (ThicknessWrapper)source;
			sender.UpdateMargin();
		}





		static void OnPropertyChanged(DependencyObject source,DependencyPropertyChangedEventArgs args)
		{
			ThicknessWrapper sender = (ThicknessWrapper)source;
			sender.UpdateMargin();
		}

		private void UpdateMargin()
		{
			if(Target != null)
			{
				var thicknessProperty = Target.GetType().GetProperty(PropertyName);
				var currentThickness = (Thickness)thicknessProperty.GetValue(Target,null);
				var nextThickness = new Thickness(
					CalculateThickness(Side.Left,currentThickness.Left),CalculateThickness(Side.Top,currentThickness.Top),CalculateThickness(Side.Right,currentThickness.Right),CalculateThickness(Side.Bottom,currentThickness.Bottom)
					);

				thicknessProperty.SetValue(Target,nextThickness,null);
			}
		}

		private double CalculateThickness(ThicknessAnimation.Side sidetoCalculate,double currentValue)
		{
			return (Side & sidetoCalculate) == sidetoCalculate ? Value : currentValue;
		}


	}

	[Flags]
	public enum Side
	{
		Left = 1,Top = 2,Right = 4,Bottom = 8,All = 15
	}
}

<Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>
            <Storyboard x:Key="animation">
                <!--<DoubleAnimation Storyboard.TargetName="rectTopMargin" Storyboard.TargetProperty="Value" From="0" To="100" Duration="00:00:1"></DoubleAnimation>-->
                <DoubleAnimation Storyboard.TargetName="rectstrokeThickness" Storyboard.TargetProperty="Value" From="0" To="20" Duration="00:00:1"></DoubleAnimation>
            </Storyboard>
        </Grid.Resources>

        <local:ThicknessWrapper x:Name="rectTopMargin" Target="{Binding ElementName=rect}" Side="Top" PropertyName="Margin"></local:ThicknessWrapper>
        <local:ThicknessWrapper x:Name="rectstrokeThickness" Target="{Binding ElementName=rect}" Side="Left,Right" PropertyName="BorderThickness"></local:ThicknessWrapper>

        <StackPanel>
            <Button Content="Click to animate" Click="Button_Click"></Button>
            <Border x:Name="rect" HorizontalAlignment="Left"  BorderBrush="Black" VerticalAlignment="Top" Background="Green" Height="50" Width="50"></Border>
        </StackPanel>
    </Grid>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐