本文主要讲我设计的几个进度条,还有如何使用异步控制进度条,如何使用动画做进度。

进度条可以参见:http://edi.wang/post/2016/2/25/windows-10-uwp-modal-progress-dialog

进度条其实异步就是使用后台变化,然后value绑定

我使用一个ProgressBar需要设置他的各个值,如果不设置,一般最大值为100,最小为0,所以可以表示百分数,其中Value是double,绑定后台就好。

“`

     <ProgressBar Maximum="100" Value="{x:Bind View.Value,Mode=OneWay}" Height="20" Width="100"></ProgressBar>

绑定到我们的ViewModel,一般如果后台线程操作界面是不能直接,但是我用了

 ```

             await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,

                () =>

                {

                });

代码参见:https://github.com/lindexi/UWP/tree/master/uwp/control/Progress,项目所有代码都会发出

我们使用Task异步,我们因为没有什么耗时的,就Task.Delay(1000).Wait();我们进度会等一秒,当然自己也可以设置多些。也可以写 await Task.Dalay(1000);

ViewModel


        public ViewModel()

        {

            new Task(() =>

            {

                while (Value < 90)

                {

                    Value += 10;

                    Task.Delay(1000).Wait();

                }

            }).Start();

        }

        public double Value

        {

            set

            {

                _value = value;

                OnPropertyChanged();

            }

            get

            {

                return _value;

            }

        }

        private double _value;

默认进度条设置最大值,

我还自己的控件,一个值从0到100的圆形的,可以看下面

##圆形进度条

参见:http://www.cnblogs.com/ms-uap/p/4641419.html

先说怎么用我的,首先去我源代码https://github.com/lindexi/UWP,打开我的进度条文件夹,里面有View文件夹

我在View有一个控件RountProgress复制他到你的解决方案,如果我的控件大小和你不一样,很简单调整,我就不说。

那么我的控件只需要指定Value就好啦,Value其实是从0到100,如果叫别的应该好,但是我不改,如果你觉得不想要,自己改

   xmlns:view="using:lindexi.uwp.control.RountProgress.View"
     <view:RountProgress Value="{x:Bind Value,Mode=OneWay}"></view:RountProgress>

我来说下怎么做

我们要知道StrokeDashArray,这个是一个数组,是循环的,也就是依此读取,知道超过长度。

首先我们需要有Thickness,宽度,StrokeDashArray的每一个都是宽度的倍数

首先取第一个元素,把这个元素乘以宽度,作为显示的大小,然后取第二个元素,乘以宽度,作为不显示的大小

然后循环获取第三个……,如果不存在第三个,那么循环拿第一做第三,n=n==max?0:n+1,n就是第n个元素

一个显示一个不显示,循环

记得长度乘以是值*宽度

那么我们如果有一个值*宽度的到大小比我们的宽度还大,那么就会截断。

假如我们宽度 3,StrokeDashArray 1,2,0.5,总长度为5,那么

第一个是大小 1*3显示,然后是2*3不显示,因为到第一个只有长度为2,第二个大小为6,所以会截断,3显示然后2不显示

我们可以用第一个为一个值,然后第二个为一个比总长度还大的值,这样会让宽度显示为我们第一个的值,而其他为空,因为第二个比最大还大

我们要做一个30%,我们需要算

长=圆*30%/宽度

圆=PI*(总长度-宽度)


         <Ellipse x:Name="Rount" Stroke="DeepSkyBlue" Height="100" Width="100" 

                 StrokeThickness="3" 

                 RenderTransformOrigin="0.5,0.5"/>

那么我们第一个值 (总长度100 - 宽度3) \* PI / 宽度3

因为我们需要算我们的宽度不是直接总长度,是总长度-宽度

第二个最好是Double.Max

我们想要一个可以用户进度,那么可以绑定一个属性,在我们控件

我们需要这个为double,然后绑定

因为我们需要两个值,所以转换

假如我们的转换是固定的总长度,宽度,那么可以使用


        public object Convert(object value, Type targetType, object parameter, string language)

        {

            double thine = 3;

            double w = 100 - thine;

            double n = Math.PI * w/thine * (double)value / 100;

            DoubleCollection temp = new DoubleCollection()

            {

               n,

                1000

            };

            return temp;

        }

如果觉得固定不好,可以在我们转换写属性,然后在界面把我们的宽度给属性,然后换为我们的宽度算,这个简单

代码在https://github.com/lindexi/UWP/tree/master/uwp/control/Progress/Progress/View/RountProgress.xaml

那么进度条如果不需要进度,那么我有一些好的,例如我之前的博客有说的,还有一个简单,也是上面改,我们一个值是显示一个值是不显示,那么我们可以做


<UserControl

    x:Class="lindexi.uwp.control.RountProgress.View.IndeterminateProgress"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:lindexi.uwp.control.RountProgress.View"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300"

    d:DesignWidth="400">

    <UserControl.Resources>

        <Style TargetType="ProgressRing">

            <Setter Property="Background" Value="Transparent"/>

            <Setter Property="Foreground" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>

            <Setter Property="IsHitTestVisible" Value="False"/>

            <Setter Property="HorizontalAlignment" Value="Center"/>

            <Setter Property="VerticalAlignment" Value="Center"/>

            <Setter Property="MinHeight" Value="20"/>

            <Setter Property="MinWidth" Value="20"/>

            <Setter Property="IsTabStop" Value="False"/>

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="ProgressRing">

                        <Grid x:Name="Ring" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" FlowDirection="LeftToRight" MaxWidth="{Binding TemplateSettings.MaxSideLength, RelativeSource={RelativeSource Mode=TemplatedParent}}" MaxHeight="{Binding TemplateSettings.MaxSideLength, RelativeSource={RelativeSource Mode=TemplatedParent}}" Padding="{TemplateBinding Padding}" RenderTransformOrigin=".5,.5" >

                            <Grid.Resources>

                                <Style x:Key="ProgressRingEllipseStyle" TargetType="Ellipse">

                                    <Setter Property="Opacity" Value="0"/>

                                    <Setter Property="HorizontalAlignment" Value="Left"/>

                                    <Setter Property="VerticalAlignment" Value="Top"/>

                                </Style>

                            </Grid.Resources>

                            <VisualStateManager.VisualStateGroups>

                                <VisualStateGroup x:Name="SizeStates">

                                    <VisualState x:Name="Large">

                                        <Storyboard>

                                        </Storyboard>

                                    </VisualState>

                                    <VisualState x:Name="Small"/>

                                </VisualStateGroup>

                                <VisualStateGroup x:Name="ActiveStates">

                                    <VisualState x:Name="Inactive"/>

                                    <VisualState x:Name="Active">

                                        <Storyboard RepeatBehavior="Forever">

                                            <DoubleAnimation Storyboard.TargetName="Rount" Storyboard.TargetProperty="Angle"

                                                           BeginTime="0:0:0" Duration="0:0:5" From="0" To="360"  >

                                            </DoubleAnimation>

                                        </Storyboard>

                                    </VisualState>

                                </VisualStateGroup>

                            </VisualStateManager.VisualStateGroups>

                            <Ellipse  Stroke="DeepSkyBlue" Height="100" Width="100" 

                                      StrokeThickness="3"  

                                      RenderTransformOrigin="0.5,0.5"/>

                            <Ellipse  Stroke="DeepSkyBlue" Height="200" Width="200" 

                                      StrokeThickness="3" StrokeDashArray="50 50" 

                                      RenderTransformOrigin="0.5,0.5" >

                                <Ellipse.RenderTransform>

                                    <RotateTransform  x:Name="Rount" Angle="0"/>

                                </Ellipse.RenderTransform>

                            </Ellipse>

                        </Grid>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

    </UserControl.Resources>

    <Grid>

        <ProgressRing Width="200" Height="200" 

                      IsActive="True"></ProgressRing>

    </Grid>

</UserControl>

我们使用一个简单的修改,因为我们可以使用<RotateTransform x:Name="Rount" Angle="0"/>

我们使用


                                    <VisualState x:Name="Active">

                                        <Storyboard RepeatBehavior="Forever">

                                            <DoubleAnimation Storyboard.TargetName="Rount" Storyboard.TargetProperty="Angle"

                                                             Duration="0:0:5" From="0" To="360"  >

                                            </DoubleAnimation>

                                        </Storyboard>

                                    </VisualState>

修改我们旋转,时间0:0:5,5秒,从0到360,循环

因为是修改,所以可以放在Resource


<ProgressRing Width="200" Height="200" 

                      IsActive="True"></ProgressRing>

我觉得匀速不好,修改速度

  • BackEase

    缓动函数,它在部分持续时间内向反方向更改主函数的值

  • BounceEase

    弹跳

  • CircleEase

    加速

  • PowerEase

    次方

  • SineEase

    sin加速

  • QuadraticEase

    ^2

    动画

    移动元素

    我们可以看到我们的元素位置可以修改Margin,那么如何在动画修改Margin

    UWP动画Margin可以


 <Storyboard TargetName="Rount">

    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin"

                                   BeginTime="00:00:00" EnableDependentAnimation="True"

                                   Duration="0:0:2" >

                 <DiscreteObjectKeyFrame KeyTime="00:00:00"  >

                     <DiscreteObjectKeyFrame.Value >

                         <Thickness>10,1,10,10</Thickness>

                     </DiscreteObjectKeyFrame.Value>

                   </DiscreteObjectKeyFrame>

                 <DiscreteObjectKeyFrame KeyTime="00:00:02">

                     <DiscreteObjectKeyFrame.Value >

                         <Thickness>10,200,10,10</Thickness>

                 </DiscreteObjectKeyFrame.Value>

         </DiscreteObjectKeyFrame>

    </ObjectAnimationUsingKeyFrames>

 </Storyboard>

Rount就是我们要修改的控件,我们看到这是在2就直接修改,没有从1到200,这样其实并不是我们直接就想从1然后两秒200

我们定义

                            <local:IndeterminateProgress  Margin="0,10,0,0" Width="200" Height="200" >

                                <local:IndeterminateProgress.RenderTransform>

                                    <TranslateTransform x:Name="Rount" Y="0"></TranslateTransform>

                                </local:IndeterminateProgress.RenderTransform>

                            </local:IndeterminateProgress>

 <DoubleAnimation Storyboard.TargetName="Rount" Storyboard.TargetProperty="Y"

        From="0" To="100" Duration="0:0:2"></DoubleAnimation>

我们要让我们的进度弹起来,如果不知道我说什么,简单我有图

其实我们要让我们的元素移动,可以看林政大神的书



    <local:IndeterminateProgress Margin="0,10,0,0" Width="200" Height="200" >

       <local:IndeterminateProgress.RenderTransform>

               <TranslateTransform x:Name="Rount" Y="10" />

       </local:IndeterminateProgress.RenderTransform>

    </local:IndeterminateProgress>

在动画


                                              <DoubleAnimation Storyboard.TargetName="Rount"

                                                             Storyboard.TargetProperty="Y"

                                                             Duration="0:0:2" From="0" To="300">

                                                <DoubleAnimation.EasingFunction>

                                                    <BounceEase Bounces="2"></BounceEase>

                                                </DoubleAnimation.EasingFunction>

                                            </DoubleAnimation>

我们使用Rount,x,记得要给名字,然后两秒,从0到300,下面就是弹跳,我上面有说,这个在官方有说比我写还好,但是官方的我没法拿来


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

win10 uwp 异步进度条的更多相关文章

  1. Win10的UWP之进度条

    原文:Win10的UWP之进度条 关于UWP的进度条的处理的方案有两种方案 我们新建一个项目,然后处理的界面如下的代码 <Grid.RowDefinitions> <RowDefin ...

  2. winform异步进度条LongTime

    winform异步进度条LongTime,运用到回调函数 定义事件的参数类: namespace LongTime.Business { // 定义事件的参数类 public class ValueE ...

  3. win10 uwp 异步转同步

    原文:win10 uwp 异步转同步 有很多方法都是异步,那么如何从异步转到同步? 可以使用的方法需要获得是否有返回值,返回值是否需要. 如果需要返回值,使用GetResults 如从文件夹获取文件: ...

  4. c# 异步进度条组件BackgroundWorker

    //控件事件调用DoWork()方法就行. #region 进度条 private BackgroundWorker worker = null; private void DoWork(string ...

  5. 2018-2-13-win10-uwp-异步进度条

    title author date CreateTime categories win10 uwp 异步进度条 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17 ...

  6. asp.net XMLHttpRequest 进度条以及lengthComputable always false的解决办法

    一直用ajax好长时间了,对其原理也有一些了解,最近由于项目需要,使用ajax异步进度条的效果,就研究了一下,用原生的XMLHttpRequest实现进度条函数,XMLHttpRequest有以下函数 ...

  7. win10 uwp 进度条 WaveProgressControl

    昨天看到了有个大神做出好看的进度条样式,于是我就去抄袭他的代码,但是发现看不懂,于是本文主要翻译就是大神说这个控件如何做. 本文翻译 https://stackoverflow.com/a/46057 ...

  8. win10 uwp 进度条 Marquez

    本文将告诉大家,如何做一个带文字的进度条,这个进度条可以用在游戏,现在我做的挂机游戏就使用了他. 如何做上图的效果,实际需要的是两个控件,一个是显示文字 的 TextBlock 一个是进度条. 那么如 ...

  9. JS -- 异步加载进度条

    今天在博客园问答里面看到博友问道怎么实现Ajax异步加载产生进度条. 很好奇就自己写了一个. 展现效果: 1) 当点击Load的时候,模拟执行异步加载. 浏览器被遮挡. 进度条出现. 实现思路: 1. ...

随机推荐

  1. 201521123034《Java程序设计》第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1) 1.1 实验总结 答:这题是在课堂上 ...

  2. 201521123016 《Java程序设计》第8周学习总结

    1. 本周学习总结 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 1.删除元素的时候从最后一个元素开始,避免删除元素后位置发生变化而导致有些元素没有删 ...

  3. 201521123076《java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  4. 201521123069 《Java程序设计》 第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  5. 201521123031 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  6. informix服务端口和oralce服务端口

    查找informix的服务端口1>>more .profile 找到: INFORMIXDIR=/home/informix INFORMIXSERVER=aaaa2>>cd ...

  7. Javascript-正则表达式-开发中的使用.

    -- "(-1~99)之间 -1表示无限次!" pattern="^((-1)|([0-9]{0,2}))$" -- "(0~99.99)之间 的金额 ...

  8. java 利用反射构造泛型类

    1.构造BaseDao泛型类 class BaseDao<T>{ private Class<T> entityClass; // 通过反射获取实际运行的精确类 public ...

  9. iOS多线程编程

    废话不多说,直接上干货.先熟悉一下基本知识,然后讲一下常用的两种,NSOperation和GCD. 一.基础概念 进程: 狭义定义:进程是正在运行的程序的实例(an instance of a com ...

  10. 实现一个简单的虚拟DOM

    现在的流行框架,无论React还是Vue,都采用虚拟DOM. 好处就是,当我们数据变化时,无需像Backbone那样整体重新渲染,而是局部刷新变化部分,如下组件模版: <ul class=&qu ...