SL/WPF仿WIN8进度条最近换到了win8,win8风格的进度条挺好玩的。可惜wpf上没有这个控件。那咱就自己来写一个吧。 用SL封装了个效果:
思路:这个过程可以分为3个阶段,最左边开始一个快速移动动画到中间位置,开始缓慢的做位移,然后再开始快速的飞到最右边,消失。且在第一个点缓动的时候,第二个点开始启动,依次类推,到最后一个点飞到最右边的时候,再启动第一个点。如此循环。 XAML:主要是定义4个点,以及每个点的动画。
<UserControl x:Class="Win8ProcessBar.CtlWin8ProcessBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas./markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Height="20" Loaded="UserControl_Loaded" Initialized="CtlWin8ProcessBar_OnInitialized"> <Canvas> <Ellipse x:Name="el" Width="6" Height="6" Fill="Black" Canvas.Top="7" Canvas.Left="0" Opacity="0"> <Ellipse.Resources> <Storyboard x:Key="sbLeft" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="el"> <DoubleAnimation From="{Binding Path=LeftFrom, Mode=OneWay}" To="{ Binding Path=LeftTo, Mode=OneWay}" Duration="0:0:0.25"> </DoubleAnimation> </Storyboard> <Storyboard x:Key="sbSlow" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="el"> <DoubleAnimation From="{Binding Path=SlowFrom, Mode=OneWay}" To="{ Binding Path=SlowTo, Mode=OneWay}" Duration="0:0:1"> </DoubleAnimation> </Storyboard> <Storyboard x:Key="sbRight" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="el"> <DoubleAnimation From="{Binding Path=RightFrom, Mode=OneWay}" To="{ Binding Path=RightTo, Mode=OneWay}" Duration="0:0:0.25"> </DoubleAnimation> </Storyboard> </Ellipse.Resources> </Ellipse> <Ellipse x:Name="el1" Width="6" Height="6" Fill="Black" Canvas.Top="7" Canvas.Left="0" Opacity="0"> <Ellipse.Resources> <Storyboard x:Key="sbLeft1" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="el1"> <DoubleAnimation From="{Binding Path=LeftFrom, Mode=OneWay}" To="{ Binding Path=LeftTo, Mode=OneWay}" Duration="0:0:0.25"> </DoubleAnimation> </Storyboard> <Storyboard x:Key="sbSlow1" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="el1"> <DoubleAnimation From="{Binding Path=SlowFrom, Mode=OneWay}" To="{ Binding Path=SlowTo, Mode=OneWay}" Duration="0:0:1"> </DoubleAnimation> </Storyboard> <Storyboard x:Key="sbRight1" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="el1"> <DoubleAnimation From="{Binding Path=RightFrom, Mode=OneWay}" To="{ Binding Path=RightTo, Mode=OneWay}" Duration="0:0:0.25"> </DoubleAnimation> </Storyboard> </Ellipse.Resources> </Ellipse> ===========================================这里省略2个点的定义================================================== </Canvas> </UserControl> cs:
//作者: minjie.zhou
// 创建时间: 2013/4/21 23:51:59 namespace Win8ProcessBar { /// <summary> /// UProgressBar.xaml 的交互逻辑 /// </summary> public partial class CtlWin8ProcessBar : UserControl, INotifyPropertyChanged { public CtlWin8ProcessBar() { InitializeComponent(); } private void UserControl_Loaded(object sender, RoutedEventArgs e) { if (double.IsNaN(Width))//默认为400的宽度 { Width = 400; } LeftFrom = 0; LeftTo = Width / 2 - (Width /7) / 2; SlowFrom = LeftTo; SlowTo = LeftTo + (Width / 7); RightFrom = SlowTo; RightTo = Width; Start(); } #region 属性 private double _leftFrom; /// <summary> /// 左边第一个起点 /// </summary> public double LeftFrom { get { return _leftFrom; } set { _leftFrom = value; if (this.PropertyChanged != null) { NotifyPropertyChanged("LeftFrom"); } } } private double _leftTo; /// <summary> /// 第一个终点 /// </summary> public double LeftTo { get { return _leftTo; } set { _leftTo = value; if (this.PropertyChanged != null) { NotifyPropertyChanged("LeftTo"); } } } private double _slowFrom; /// <summary> /// 缓动起点 /// </summary> public double SlowFrom { get { return _slowFrom; } set { _slowFrom = value; if (this.PropertyChanged != null) { NotifyPropertyChanged("SlowFrom"); } } } private double _slowTo; /// <summary> /// 缓动终点 /// </summary> public double SlowTo { get { return _slowTo; } set { _slowTo = value; if (this.PropertyChanged != null) { NotifyPropertyChanged("SlowTo"); } } } private double _rightFrom; /// <summary> /// 右边起点 /// </summary> public double RightFrom { get { return _rightFrom; } set { _rightFrom = value; if (this.PropertyChanged != null) { NotifyPropertyChanged("RightFrom"); } } } private double _rightTo; /// <summary> /// 右边终点 /// </summary> public double RightTo { get { return _rightTo; } set { _rightTo = value; if (this.PropertyChanged != null) { NotifyPropertyChanged("RightTo"); } } } #endregion private void CtlWin8ProcessBar_OnInitialized(object sender, EventArgs e) { this.DataContext = this; this.el.Opacity = 0; this.el1.Opacity = 0; this.el2.Opacity = 0; this.el3.Opacity = 0; var sbLeft = this.el.FindResource("sbLeft") as Storyboard; var sbSlow = this.el.FindResource("sbSlow") as Storyboard; var sbRight = this.el.FindResource("sbRight") as Storyboard; var sbLeft1 = this.el1.FindResource("sbLeft1") as Storyboard; var sbSlow1 = this.el1.FindResource("sbSlow1") as Storyboard; var sbRight1 = this.el1.FindResource("sbRight1") as Storyboard; var sbLeft2 = this.el2.FindResource("sbLeft2") as Storyboard; var sbSlow2 = this.el2.FindResource("sbSlow2") as Storyboard; var sbRight2 = this.el2.FindResource("sbRight2") as Storyboard; var sbLeft3 = this.el3.FindResource("sbLeft3") as Storyboard; var sbSlow3 = this.el3.FindResource("sbSlow3") as Storyboard; var sbRight3 = this.el3.FindResource("sbRight3") as Storyboard; //第一个点第一个动画结束后开启缓动,第二个点启动 sbLeft.Completed += (a, b) => { sbSlow.Begin(); el1.Opacity = 1; sbLeft1.Begin(); }; //第一个点缓动结束,右边动画启动 sbSlow.Completed += (a, b) => sbRight.Begin(); sbRight.Completed += (a, b) => el.Opacity = 0; //以下类推 sbLeft1.Completed += (a, b) => { sbSlow1.Begin(); el2.Opacity = 1; sbLeft2.Begin(); }; sbSlow1.Completed += (a, b) => sbRight1.Begin(); sbRight1.Completed += (a, b) => el1.Opacity = 0; sbLeft2.Completed += (a, b) => { sbSlow2.Begin(); el3.Opacity = 1; sbLeft3.Begin(); }; sbSlow2.Completed += (a, b) => sbRight2.Begin(); sbRight2.Completed += (a, b) => el2.Opacity = 0; sbLeft3.Completed += (a, b) => sbSlow3.Begin(); sbSlow3.Completed += (a, b) => sbRight3.Begin(); //最后一个点动画结束,第一个点重启 如此循环 sbRight3.Completed += (a, b) => { el3.Opacity = 0; el.Opacity = 1; sbLeft.Begin(); }; } public void Start() { var sb = this.el.FindResource("sbLeft") as Storyboard; this.el.Opacity = 1; if (sb != null) sb.Begin(); } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } } 重点: Storyboard在sl/WPF里面做动画的时候有很大的作用。配合DoubleAnimation可以在一段时间内改变某个对象的double型属性。比如透明值在1秒内1到0。上面例子就是做了一个在一段时间内Canvas.Left属性从0到最右边的动画。配合ColorAnimation可以在2种颜色之间做渐变。 |
|
来自: xyjackxjw > 《Animation》