• WPF:Metro样式ProgressBar(圆点横向移动),自适应宽度


    先看效果图:

    最直观的,这是4个圆点在移动,就用一个横向的StackPanel表示这四个点吧。

    <StackPanel Orientation="Horizontal">
            <StackPanel.Resources>
                <Style TargetType="{x:Type Border}">
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="BorderThickness" Value="0"/>
                    <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl, AncestorLevel=1}, Path= Foreground}"/>
                    <Setter Property="CornerRadius" Value="100"/>
                    <Setter Property="Height" Value="4"/>
                    <Setter Property="Width" Value="4"/>
                </Style>
            </StackPanel.Resources>
            <Border x:Name="border4" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            </Border>
            <Border x:Name="border3" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            </Border>
            <Border x:Name="border2" Margin="0,0,5,0" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            </Border>
            <Border x:Name="border1" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            </Border>
        </StackPanel>

    圆点的颜色绑定在用户控件的Foreground上面。在调用控件的时候记得对其Foreground赋值以便显示适合的颜色。

    这个动画实际上很简单,分为5个部分:

    1.准备部分:准备向前移动

    2.正向加速度部分:移动速度越来越快

    3.匀速部分:慢速匀速移动

    4.负向加速度部分:移动速度越来越慢

    5.等待部分:等待所有动画完成

    动画代码如下:

    <Storyboard x:Key="sbKey" Completed="Storyboard_Completed"  >
                <!--最右边-->
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border1">
                    <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.8">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1.2"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:2">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseIn"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.6"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border2">
                    <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0" x:Name="_2_1">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="190" x:Name="_2_2">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1.3" Value="210" x:Name="_2_3"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.1" Value="400" x:Name="_2_4">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseIn"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.6" Value="400" x:Name="_2_5"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border3">
                    <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0" x:Name="_3_1">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="190" x:Name="_3_2">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1.4" Value="210" x:Name="_3_3"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.2" Value="400" x:Name="_3_4">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseIn"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.6" Value="400" x:Name="_3_5"/>
                </DoubleAnimationUsingKeyFrames>
                <!--最左边-->
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="border4">
                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0" x:Name="_4_1">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="190" x:Name="_4_2">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseOut"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="210" x:Name="_4_3"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.3" Value="400" x:Name="_4_4">
                        <EasingDoubleKeyFrame.EasingFunction>
                            <CircleEase EasingMode="EaseIn"/>
                        </EasingDoubleKeyFrame.EasingFunction>
                    </EasingDoubleKeyFrame>
                    <EasingDoubleKeyFrame KeyTime="0:0:2.6" Value="400" x:Name="_4_5"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>

    由于动画需要自适应宽度,所以部分关键帧的值无法在XAML中表现出来,只有在后台进行动态处理。

    当控件的宽度发生变化时需要更新动画部分关键帧:

    /// <summary>
            /// 当控件的大小发生变化时
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                //当控件的宽度发生变化时
                if(e.WidthChanged)
                {
                    isNeedUpdateStoryboard = true;
                }
            }

    当动画每一次执行完毕后,下一次执行之前,判断是否需要更新部分关键帧,所以响应动画的Completed事件:

    /// <summary>
            /// 动画执行完毕
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Storyboard_Completed(object sender, EventArgs e)
            {
                //每次动画执行完毕后判断是否需要更新动画
                if(isNeedUpdateStoryboard)
                {
                    UpdateStoryboard();
                }
    
                isNeedUpdateStoryboard = false;
                storyboard.Begin(this);
            }
    /// <summary>
            /// 更新动画部分关键帧
            /// </summary>
            private void UpdateStoryboard()
            {
                //获取控件的实际宽度,减去4个点占用的宽度
                double realWidth = this.ActualWidth - 36;
                //正向加速度占比47.5%
                double _0Width = realWidth * 0.475;
                //匀速部分占比5%
                double _1Width = _0Width + realWidth * 0.05;
    
                //根据控件的实际大小动态更改动画
                #region 右边第一个
                var _0 = storyboard.Children[0] as DoubleAnimationUsingKeyFrames;
                var _0_1 = _0.KeyFrames[1] as EasingDoubleKeyFrame;
                var _0_2 = _0.KeyFrames[2] as EasingDoubleKeyFrame;
                var _0_3 = _0.KeyFrames[3] as EasingDoubleKeyFrame;
                var _0_4 = _0.KeyFrames[4] as EasingDoubleKeyFrame;
    
                _0_1.Value = _0Width;
                _0_2.Value = _1Width;
                _0_3.Value = realWidth;
                _0_4.Value = realWidth;
                #endregion
    
                #region 右边倒数第二个
                var _1 = storyboard.Children[1] as DoubleAnimationUsingKeyFrames;
                var _1_1 = _1.KeyFrames[1] as EasingDoubleKeyFrame;
                var _1_2 = _1.KeyFrames[2] as EasingDoubleKeyFrame;
                var _1_3 = _1.KeyFrames[3] as EasingDoubleKeyFrame;
                var _1_4 = _1.KeyFrames[4] as EasingDoubleKeyFrame;
    
                _1_1.Value = _0Width;
                _1_2.Value = _1Width;
                _1_3.Value = realWidth;
                _1_4.Value = realWidth;
                #endregion
    
                #region 右边倒数第三个
                var _2 = storyboard.Children[2] as DoubleAnimationUsingKeyFrames;
                var _2_1 = _2.KeyFrames[1] as EasingDoubleKeyFrame;
                var _2_2 = _2.KeyFrames[2] as EasingDoubleKeyFrame;
                var _2_3 = _2.KeyFrames[3] as EasingDoubleKeyFrame;
                var _2_4 = _2.KeyFrames[4] as EasingDoubleKeyFrame;
    
                _2_1.Value = _0Width;
                _2_2.Value = _1Width;
                _2_3.Value = realWidth;
                _2_4.Value = realWidth;
                #endregion
    
                #region 右边倒数第四个
                var _3 = storyboard.Children[3] as DoubleAnimationUsingKeyFrames;
                var _3_1 = _3.KeyFrames[1] as EasingDoubleKeyFrame;
                var _3_2 = _3.KeyFrames[2] as EasingDoubleKeyFrame;
                var _3_3 = _3.KeyFrames[3] as EasingDoubleKeyFrame;
                var _3_4 = _3.KeyFrames[4] as EasingDoubleKeyFrame;
    
                _3_1.Value = _0Width;
                _3_2.Value = _1Width;
                _3_3.Value = realWidth;
                _3_4.Value = realWidth;
                #endregion
            }

    最后提供动画的开始和结束调用:

    /// <summary>
            /// 使进度条开始滚动
            /// </summary>
            public void Start()
            {
                this.Visibility = System.Windows.Visibility.Visible;
                UpdateStoryboard();
                storyboard.Begin(this, true);
            }
            /// <summary>
            /// 使进度条停止滚动
            /// </summary>
            public void Stop()
            {
                this.Visibility = System.Windows.Visibility.Collapsed;
                storyboard.Stop(this);
            }

    源代码下载:http://download.csdn.net/detail/lyclovezmy/7598897

  • 相关阅读:
    uni-app拒绝授权后再次授权
    vue触底操作
    vue滚动条滚到到底部触发的方法
    pagination插件使用例子
    修改后台返回数据的字段
    v-cloak指令的作用
    修改checkbox样式
    获取selected的值
    前端工程师必备的几个实用网站
    html发展史简介(摘抄)
  • 原文地址:https://www.cnblogs.com/DoNetCoder/p/3826870.html
Copyright © 2020-2023  润新知