因为在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] 举报,一经查实,本站将立刻删除。