WPF的实现方式有多种,使用演示图板对属性进行动画处理、不使用演示图板对属性进行动画处理
这里分别记录两种操作方式
(1)使用演示图板对属性进行动画处理
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<StackPanel Margin="30" HorizontalAlignment="Left" MinWidth="500"> <TextBlock>Storyboard Animation Example</TextBlock> <!-- The width of this button is animated. --> <Button Content="A Button" Name="myWidthAnimatedButton" Height="30" Width="200" HorizontalAlignment="Left"> <Button.Triggers> <!-- Animates the width of the first button from 200 to 300. --> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="myWidthAnimatedButton" Storyboard.TargetProperty="Width" From="200" To="300" Duration="0:0:3" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button> <!-- The color of the brush used to paint this button is animated. --> <Button Content="Another Button" Height="30" Width="200" HorizontalAlignment="Left"> <Button.Background> <SolidColorBrush x:Name="myAnimatedBrush" Color="Blue" /> </Button.Background> <Button.Triggers> <!-- Animates the color of the brush used to paint the second button from red to blue . --> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetName="myAnimatedBrush" Storyboard.TargetProperty="Color" From="Red" To="Blue" Duration="0:0:7" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button> </StackPanel>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
this.Title = "Animate Properties using Storyboards"; #region 容器 //定义一个stackpanel作为容器 StackPanel myStackPanel = new StackPanel(); myStackPanel.MinWidth = 500; myStackPanel.Margin = new Thickness(30); myStackPanel.HorizontalAlignment = HorizontalAlignment.Left; //容器添加到当前窗体 this.AddChild(myStackPanel); #endregion #region 第一个按钮动画 // 创建一个按钮 Button myWidthAnimatedButton = new Button(); myWidthAnimatedButton.Height = 30; myWidthAnimatedButton.Width = 200; myWidthAnimatedButton.HorizontalAlignment = HorizontalAlignment.Left; myWidthAnimatedButton.Content = "A Button"; // Set the Name of the button so that it can be referred // to in the storyboard that's created later. // The ID doesn't have to match the variable name; // it can be any unique identifier. myWidthAnimatedButton.Name = "myWidthAnimatedButton"; //Create a name scope for the Window NameScope.SetNameScope(this, new NameScope()); // Register the name with the Window to which the button belongs. this.RegisterName(myWidthAnimatedButton.Name, myWidthAnimatedButton); // Create a DoubleAnimation to animate the width of the button. DoubleAnimation myDoubleAnimation = new DoubleAnimation(); myDoubleAnimation.From = 200; myDoubleAnimation.To = 300; myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000)); // Configure the animation to target the button's Width property. Storyboard.SetTargetName(myDoubleAnimation, myWidthAnimatedButton.Name); Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Button.WidthProperty)); // Create a storyboard to contain the animation. Storyboard myWidthAnimatedButtonStoryboard = new Storyboard(); myWidthAnimatedButtonStoryboard.Children.Add(myDoubleAnimation); // Animate the button width when it's clicked. myWidthAnimatedButton.Click += (sender, args) => myWidthAnimatedButtonStoryboard.Begin(this); myStackPanel.Children.Add(myWidthAnimatedButton); #endregion #region 第二个按钮动画 // Create a second button. Button myColorAnimatedButton = new Button(); myColorAnimatedButton.Height = 30; myColorAnimatedButton.Width = 200; myColorAnimatedButton.HorizontalAlignment = HorizontalAlignment.Left; myColorAnimatedButton.Content = "Another Button"; // Create a SolidColorBrush to paint the button's background. SolidColorBrush myBackgroundBrush = new SolidColorBrush(); myBackgroundBrush.Color = Colors.Blue; // Because a Brush isn't a FrameworkElement, it doesn't // have a Name property to set. Instead, you just // register a name for the SolidColorBrush with // the page where it's used. this.RegisterName("myAnimatedBrush", myBackgroundBrush); // Use the brush to paint the background of the button. myColorAnimatedButton.Background = myBackgroundBrush; // Create a ColorAnimation to animate the button's background. ColorAnimation myColorAnimation = new ColorAnimation(); myColorAnimation.From = Colors.Red; myColorAnimation.To = Colors.Blue; myColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(7000)); // Configure the animation to target the brush's Color property. Storyboard.SetTargetName(myColorAnimation, "myAnimatedBrush"); Storyboard.SetTargetProperty(myColorAnimation, new PropertyPath(SolidColorBrush.ColorProperty)); // Create a storyboard to contain the animation. Storyboard myColorAnimatedButtonStoryboard = new Storyboard(); myColorAnimatedButtonStoryboard.Children.Add(myColorAnimation); // Animate the button background color when it's clicked. myColorAnimatedButton.Click += (sender, args) => myColorAnimatedButtonStoryboard.Begin(myColorAnimatedButton); myStackPanel.Children.Add(myColorAnimatedButton); #endregion
后台代码方式比较麻烦,代码量比较大,但是更灵活,也更容易理解storyboard的工作方式
这里有两个地方纠结了很久,不清楚是干什么用的,结果删掉之后,提示"不存在可解析名称XXXX的适用名称领域"
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//Create a name scope for the Window NameScope.SetNameScope(this, new NameScope()); // Register the name with the Window to which the button belongs. this.RegisterName(myWidthAnimatedButton.Name, myWidthAnimatedButton);
原来我们在写
Storyboard.SetTargetName(myDoubleAnimation, myWidthAnimatedButton.Name);
的时候是通过元素名称映射元素对象的,我们定义完元素之后没有注册,执行myWidthAnimatedButtonStoryboard.Begin(this)的时候,
方法就找不到元素。NameScope类具体使用参考 这里
(2)在不使用演示图板的情况下对属性进行动画处理
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
WindowTitle = "Local Animation Example"; StackPanel myStackPanel = new StackPanel(); myStackPanel.Margin = new Thickness(20); // Create and set the Button. Button aButton = new Button(); aButton.Content = "A Button"; // Animate the Button's Width. DoubleAnimation myDoubleAnimation = new DoubleAnimation(); myDoubleAnimation.From = 75; myDoubleAnimation.To = 300; myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5)); myDoubleAnimation.AutoReverse = true; myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever; // Apply the animation to the button's Width property. aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation); // Create and animate a Brush to set the button's Background. SolidColorBrush myBrush = new SolidColorBrush(); myBrush.Color = Colors.Blue; ColorAnimation myColorAnimation = new ColorAnimation(); myColorAnimation.From = Colors.Blue; myColorAnimation.To = Colors.Red; myColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(7000)); myColorAnimation.AutoReverse = true; myColorAnimation.RepeatBehavior = RepeatBehavior.Forever; // Apply the animation to the brush's Color property. myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation); aButton.Background = myBrush; // Add the Button to the panel. myStackPanel.Children.Add(aButton); this.Content = myStackPanel;
同样可以实现,但是灵活性就降低了,例如不能更好的控制时间线、停止、暂停,不容易多个动画组合
参考 http://msdn.microsoft.com/zh-cn/library/ms752312%28v=vs.100%29.aspx
http://www.cnblogs.com/zhouyinhui/archive/2007/04/10/706107.html