`
lindexi-gd
  • 浏览: 140230 次
社区版块
存档分类
最新评论

win10 uwp 异步进度条

 
阅读更多

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

进度条可以参见: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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    lindexi#lindexi.github.io#win10 uwp 异步转同步1

    如果需要反过来,把同步转异步,可以使用 同步方法转异步写你的代码使用Task.Wait 时需要小心死锁不会出现死锁的代码使用Task.Delay等待即使使用方法

    UWP环状进度条

    以上就是如何在UWP应用中创建一个带有百分比显示的环形进度条。通过自定义控件和模板绑定,我们可以扩展原生组件的功能,使其更好地满足我们的需求。这个过程涉及到XAML布局、依赖属性以及控件模板等UWP开发的核心...

    Win10 UWP 开发教程 课程 资源

    Win10 UWP 开发教程 课程 资源 80课时 课程地址:http://blog.csdn.net/shanguuncle/article/details/78111649

    Win10 UWP应用代理工具

    全选设置之后UWP即可访问localhost,可以走代理。

    Win10下通过UWP刷新WIFI

    下面我们将深入探讨如何在Win10下通过UWP实现这些功能。 首先,我们需要了解UWP(Universal Windows Platform)是微软为Windows 10推出的一种跨设备的应用程序开发框架。它允许开发者编写一次代码,就能在各种...

    win10 uwp 轻量级 MVVM 框架入门 2.1.5.3199 例子

    总结来说,"win10 uwp 轻量级 MVVM 框架入门 2.1.5.3199 例子"提供了一个实际操作的平台,让开发者学习如何在UWP环境中利用MVVM模式进行开发。通过分析和实践这个框架,你将能够更好地理解MVVM的工作原理,以及如何...

    C#实现win10 uwp 右击浮出窗在点击位置

    在Windows 10 UWP应用开发中,常常需要创建一种用户友好的交互方式,即当用户右键点击某个元素时,能在一个特定的位置显示一个浮出菜单(MenuFlyout)。本篇文章将详细介绍如何使用C#实现这样的功能,使得MenuFlyout...

    win10 uwp 使用 asp dotnet core 做图床服务器客户端

    在本文中,我们将探讨如何利用Windows 10的UWP(通用Windows平台)应用程序与ASP.NET Core构建一个图床服务器的客户端。这是一个涉及到跨平台开发和云端图像存储管理的项目,旨在提供一种高效且灵活的方式来上传和...

    android 中win10 使用uwp控件实现进度条Marquez效果

    Android 中使用 UWP 控件实现进度条 Marquez 效果 本文主要介绍了在 Android 中使用 UWP 控件实现进度条 Marquez 效果的方法。进度条控件是游戏开发中常用的控件之一,能够显示游戏的进度,提高用户的游戏体验。 ...

    win10 moblie uwp qq5.6.1150.1000

    win10 moblie uwp qq5.6.1150.1000主程序,不含依赖程序

    lindexi#lindexi#2020-10-28-win10-uwp-字符文本转语音声音文件方法1

    title: "win10 uwp 字符文本转语音声音文件方法"在 UWP 中,支持将传入的字符串文本内容转换为音频语音,可以将这个语音声音通过 MediaEl

    win10 moblie uwp 越飞阅读1.4.68.0

    win10 moblie uwp 越飞阅读1.4.68.0主程序,不含依赖程序

    lindexi#lindexi.github.io#win10 uwp 使用 AppCenter 自动构建1

    首先打开 使用微软的账号或 github 账号登陆点击 add new 添加一个 UWP 程序,需要写出 app 的

    WindowsStore_LTSC2019,LTSC 自动恢复 win10 应用商店

    但是LTSB/C也没了应用商店和UWP运行环境.,LTSC自动恢复win10应用商店,应用商店也是Win10的一大特色! Win10的应用商店也有一些优秀的应用可以代替臃肿的桌面程序. 使用该工具即可在 Windows10 LTSC(2019,1809) 上...

    WindowsStore_LTSC2019,LTSC自动恢复win10应用商店

    但是LTSB/C也没了应用商店和UWP运行环境.,LTSC自动恢复win10应用商店,应用商店也是Win10的一大特色! Win10的应用商店也有一些优秀的应用可以代替臃肿的桌面程序. 使用该工具即可在 Windows10 LTSC(2019,1809) 上安装...

    uwp开发-demoHelloworld源码

    【描述】提到的"一个uwp开发源码,可以移植到一切win10系统"意味着该项目遵循了UWP的跨平台特性,使得开发者能够在不同类型的Windows 10设备上部署和运行同一套代码。UWP是微软为了统一Windows生态而推出的新开发...

    Sound Blaster Connect的uwp版独立安装包

    此安装包为win10的uwp版应用软件Sound Blaster Connect,有需要的朋友可以去下载下来

    win10应用商店uwp安装包

    win10应用商店安装包,Microsoft.WindowsStore_11804.1001.913.0_neutral_~_8wekyb3d8bbwe,可用于不带应用商店的安装

    Win10 资源管理器替代工具 FilesUWP 1.5.0.0 中文免费版.zip

    借助 Windows Explorer 上的这种现代 UWP,以更有效,更令人满意的方式管理文件 我们认为我们大多数人都可以同意 Windows 10 是迄今为止 Microsoft 操作系统的最佳版本,尽管它具有各种可感知的或多或少的主观缺点...

Global site tag (gtag.js) - Google Analytics