win10 uwp 异步进度条

Cle****-he UID.1073626
2016-09-23 发表

本帖最后由 Clever-he 于 2016-9-23 10:30 编辑

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

进度条可以参见:***链接停止解析***

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

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

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

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

[mw_shl_code=csharp,false]await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,

() =>

{



});[/mw_shl_code]

代码参见:***链接停止解析***,项目所有代码都会发出

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

ViewModel

[mw_shl_code=csharp,false]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;[/mw_shl_code]

默认进度条设置最大值,

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

圆形进度条

参见:***链接停止解析***

先说怎么用我的,首先去我源代码***链接停止解析***,打开我的进度条文件夹,里面有View文件夹

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


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

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

***图片停止解析***

我来说下怎么做

我们要知道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*(总长度-宽度)

[mw_shl_code=csharp,false]<Ellipse x:Name="Rount" Stroke="DeepSkyBlue" Height="100" Width="100"

StrokeThickness="3"

RenderTransformOrigin="0.5,0.5"/>[/mw_shl_code]

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

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

第二个最好是Double.Max

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

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

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

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

[mw_shl_code=csharp,false]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;

}[/mw_shl_code]

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

代码在***链接停止解析***

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

***图片停止解析***

[mw_shl_code=xml,false]<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>[/mw_shl_code]

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

我们使用

[mw_shl_code=xml,false] <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>[/mw_shl_code]

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

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

[mw_shl_code=xml,false]<ProgressRing Width="200" Height="200"

IsActive="True"></ProgressRing>[/mw_shl_code]

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

[list]
[*]BackEase
[/list]
缓动函数,它在部分持续时间内向反方向更改主函数的值

[list]
[*]BounceEase
[/list]

弹跳

[list]
[*]CircleEase
[/list]
加速

[list]
[*]PowerEase
[/list]
次方
[list]
[*]SineEase
[/list]
sin加速
[list]
[*]QuadraticEase
[/list]
^2

动画

移动元素

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

UWP动画Margin可以

[mw_shl_code=xml,false]<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>[/mw_shl_code]

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

我们定义

[mw_shl_code=xml,false] <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>[/mw_shl_code]

[mw_shl_code=xml,false]<DoubleAnimation Storyboard.TargetName="Rount" Storyboard.TargetProperty="Y"

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

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

***图片停止解析***

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

[mw_shl_code=xml,false]<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>[/mw_shl_code]

在动画

[mw_shl_code=xml,false]<DoubleAnimation Storyboard.TargetName="Rount"

Storyboard.TargetProperty="Y"

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

<DoubleAnimation.EasingFunction>

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

</DoubleAnimation.EasingFunction>

</DoubleAnimation>[/mw_shl_code]

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

来自:***链接停止解析*** 开发者交流群:53078485,期待你的加入!

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报