国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > php教程 > win10 uwp 异步进度条

win10 uwp 异步进度条

来源:程序员人生   发布时间:2016-09-28 09:53:01 阅读次数:3641次

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

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

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

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

“`

     <ProgressBar Maximum="100" Value="{x:Bind View.Value,Mode=OneWay}" Height="20" Width="100"></ProgressBar>
绑定到我们的ViewModel,1般如果后台线程操作界面是不能直接,但是我用了 ``` await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { });

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

我们使用Task异步,我们由于没有甚么耗时的,就Task.Delay(1000).Wait();我们进度会等1秒,固然自己也能够设置多些。也能够写 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;

默许进度条设置最大值,

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

##圆形进度条

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

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

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

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

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

这里写图片描述

我来讲下怎样做

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

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

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

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

1个显示1个不显示,循环

记得长度乘以是值*宽度

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

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

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

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

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

长=圆*30%/宽度

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

<Ellipse x:Name="Rount" Stroke="DeepSkyBlue" Height="100" Width="100" StrokeThickness="3" RenderTransformOrigin="0.5,0.5"/>

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

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

第2个最好是Double.Max

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

我们需要这个为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

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

这里写图片描述

<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>

我们使用1个简单的修改,由于我们可使用<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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生