• 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.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));
                }
            }
        }

    } 

    重点:

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

  • 相关阅读:
    php魔术方法
    适用所有手机号码的正则表达式
    js按回车事件提交
    php 顺序线性表
    PLSQL连接远程oracle配置
    Jmeter 接口测试 —— 3种参数化方式
    Jmeter 接口测试 —— 3种采样器的使用
    【LICEcap】怎样用LICEcap录制屏幕及GIF图片
    WPS标题自动编号
    UT、IT、ST、UAT
  • 原文地址:https://www.cnblogs.com/kklldog/p/3036778.html
Copyright © 2020-2023  润新知