SL/WPF仿WIN8进度条

简介: 原文 http://www.cnblogs.com/kklldog/archive/2013/04/22/3036778.html 最近换到了win8,win8风格的进度条挺好玩的。可惜wpf上没有这个控件。

原文 http://www.cnblogs.com/kklldog/archive/2013/04/22/3036778.html

最近换到了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.openxmlformats.org/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( thisnew PropertyChangedEventArgs(propertyName));
            }
        }
    }
复制代码

} 

重点:

 Sotryboard在sl/WPF里面做动画的时候有很大的作用。配合DoubleAnimation可以在一段时间内改变某个对象的double型属性。比如透明值在1秒内1到0。上面例子就是做了一个在一段时间内Canvas.Left属性从0到最右边的动画。配合ColorAnimation可以在2种颜色之间做渐变。

目录
相关文章
|
C# 数据库 UED
C#-WPF ProgressBar进度条
进度条常用在加载,下载,导出一些比较耗时的地方,利用进度条能让用户看到实时进展,能有更好的用户体验……
580 0
|
人工智能 搜索推荐 C#
Photoshop和WPF双剑配合,打造炫酷个性的进度条控件
结合Photoshop和WPF,共同创建一个矢量的个性化进度条。
539 0
Photoshop和WPF双剑配合,打造炫酷个性的进度条控件
|
C#
WPF 绕圈进度条(二)
一 以前的方案 以前写过一个圆点绕圈的进度条,根据参数圆点个数和参数每次旋转角度,主要是在cs文件中动态添加圆点,通过后台定时器,动态设置角度后用正弦余弦计算(x,y)的位置。 此方案优点:动态添加Loading的圆点个数和Loading速度 此方案缺点:后台定时器耗性能 WPF 绕圈进度条(一) 二 现在的方案 如果有UI图标,或者自己能够设计矢量图的情况下,可以通过Xaml实现绕圈动画的设置。
1188 0
|
C#
WPF 绕圈进度条(二)
原文:WPF 绕圈进度条(二) 一 以前的方案 以前写过一个圆点绕圈的进度条,根据参数圆点个数和参数每次旋转角度,主要是在cs文件中动态添加圆点,通过后台定时器,动态设置角度后用正弦余弦计算(x,y)的位置。
838 0
|
前端开发 C#
WPF 绕圈进度条(一)
原文:WPF 绕圈进度条(一) 在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码:     1、控件界面 ...
1392 0
|
C# Windows
Photoshop和WPF双剑配合,打造炫酷个性的进度条控件
原文:Photoshop和WPF双剑配合,打造炫酷个性的进度条控件 现在如果想打造一款专业的App,UI的设计和操作的简便性相当重要。UI设计可以借助Photoshop或者AI等设计工具,之前了解到WPF设计工具Expression Blend可以直接导入PSD文件或者AI设计文件(当然不是全部特征支持),最近研究了一下,也费了一番周折,好在最后实现了预期的效果。
900 0
|
C#
WPF下载远程文件,并显示进度条和百分比
原文:WPF下载远程文件,并显示进度条和百分比 WPF下载远程文件,并显示进度条和百分比 1、xaml  2、CS程序 using System; using System.
1872 0
|
存储 前端开发 C#
WPF自定义控件第一 - 进度条控件
原文:WPF自定义控件第一 - 进度条控件 本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路。 前期一个小任务需要实现一个类似含步骤进度条的控件。虽然对于XAML的了解还不是足够深入,还是摸索着做了一个。
1242 0
|
C#
WPF 控件库——仿制Windows10的进度条
原文:WPF 控件库——仿制Windows10的进度条 一、其实有现成的   先来看看Windows10进度条的两种模式:       网上有不少介绍仿制Windows10进度条的文章,也都实现了不错的效果。
1396 0
|
C#
WPF 简单的绕圈进度条(无cs代码)
方案: 图标位置不变化的情况下设置透明度实现 代码: 0:0:.84 ...
1297 0