博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
New UWP Community Toolkit - RadialProgressBar
阅读量:5931 次
发布时间:2019-06-19

本文共 3898 字,大约阅读时间需要 12 分钟。

概述

UWP Community Toolkit  中有一个圆形的进度条控件 - RadialProgressBar,本篇我们结合代码详细讲解  RadialProgressBar 的实现。

RadialProgressBar 是一种圆形的进度条控件,进度值用圆形中的填充色的角度来表示,进度增长,填充色按照顺时针方向增加,直到占满整个圆形,则进度条达到最大值。我们来看一下官方的介绍和官网示例中的展示:

Source: 

Doc:

Namespace: Microsoft.Toolkit.Uwp.UI.Controls; Nuget: Microsoft.Toolkit.Uwp.UI.Controls;

 

开发过程

代码分析

我们来看一下 RadialProgressBar 控件的结构:

  • RadialProgressBar.cs - RadialProgressBar 控件定义类
  • RadialProgressBar.xaml - RadialProgressBar 控件样式

1. RadialProgressBar.xaml

这是 RadialProgressBar 控件的样式,我们可以看到 Template 部分由 OutlineFigurePart 和 BarFigurePart 组成,分别代表了进度条的灰色底和实际的进度条,因为两个部分的样式基本一致,所以我们省略了一部分。

可以看到,两个部分的样式组成,都是一个 Path 的几何图形,里面包含了 ParhFigure,它的 segment 属性包含了 ArcSegment:一个弧度区段;这就是样式的基本组成了。

2. RadialProgressBar.cs

看一下这个类的构成:

 

RadialProgressBar 类继承自 ProgressBar 类,表现形式为圆形的进度条,分为 outline 和 bar 两个部分,所以可以看到类中定义了 outlineFigure、barFigure、outlineArc 和 barArc 属性;而依赖属性有:

  • Thickness - 表示圆形进度条的圆环大小,默认为 0,xaml 中定义为 4
  • Outline - 表示圆形底的画刷,默认为 transparent,xaml 中定义为 gray

而继承自 ProgressBar 的 Background 和 Foreground,则分别表示进度条中间空白部分的颜色,和进度条的进度颜色。因为继承自 ProgressBar 类,所以重载了 Progress 类的几个方法:

  • OnMinimumChanged(old, new) - 进度条最小值变化的处理方法,会触发 RenderSegment() 方法;
  • OnMaximumChanged(old, new) - 进度条最大值变化的处理方法,会触发 RenderSegment() 方法;
  • OnValueChanged(old, new) - 进度条进度值变化的处理方法,会触发 RenderSegment() 方法;
  • OnApplyTemplate() - 应用模板或哦模板改变时,更新控件的视觉显示 ,会触发 RenderAll() 方法;

还有两个 Changed 处理方法:ThicknessChangedHandler(d, e) 和 SizeChangedHandler(s, e),分别处理进度条宽度变化和进度条尺寸变化,也会触发  RenderAll() 方法;

下面来看看几个主要的方法:

① ComputeNormalizedRange()

根据进度条的最大值和最小值计算出的区间,以及当前值,计算出当前值在区间中占的百分比,如果当前值 > 0.999, 则取值 0.999

private double ComputeNormalizedRange(){    var range = Maximum - Minimum;    var delta = Value - Minimum;    var output = range == 0.0 ? 0.0 : delta / range;    output = Math.Min(Math.Max(0.0, output), 0.9999);    return output;}

② ComputeEllipseSize()

计算圆形的尺寸,根据进度条的实际宽度和高度,去掉安全宽度,计算后值的 1/2 就是 Ellipse 的长短半径;

private Size ComputeEllipseSize(){    var safeThickness = Math.Max(Thickness, 0.0);    var width = Math.Max((ActualWidth - safeThickness) / 2.0, 0.0);    var height = Math.Max((ActualHeight - safeThickness) / 2.0, 0.0);    return new Size(width, height);}

③ RenderSegment()

弧形区段的实际渲染,根据当前角度,尺寸和圆环宽度,计算出当前弧形的终点坐标;同时输出一个值:IsLargeArc,角度是否 >= 180 度。

private void RenderSegment(){    if (!allTemplatePartsDefined)    {        return;    }    var normalizedRange = ComputeNormalizedRange();    var angle = 2 * Math.PI * normalizedRange;    var size = ComputeEllipseSize();    var translationFactor = Math.Max(Thickness / 2.0, 0.0);    double x = (Math.Sin(angle) * size.Width) + size.Width + translationFactor;    double y = (((Math.Cos(angle) * size.Height) - size.Height) * -1) + translationFactor;    barArc.IsLargeArc = angle >= Math.PI;    barArc.Point = new Point(x, y);}

④ RenderAll()

渲染进度条的全部控件部分,计算 outlineFigure 和 barFigure 的起始点,new Point(segmentWidth + translationFactor, translationFactor) 也就是圆形最上方的横向中心点;然后计算 outlineArc 和 barArc 的尺寸,也就是圆形半径;outlineArc 的角度固定,所以只需要给一个初始值,最后是调用 RenderSegment() 方法计算 Bar 的实际渲染部分。

private void RenderAll(){    if (!allTemplatePartsDefined)    {        return;    }    var size = ComputeEllipseSize();    var segmentWidth = size.Width;    var translationFactor = Math.Max(Thickness / 2.0, 0.0);    outlineFigure.StartPoint = barFigure.StartPoint = new Point(segmentWidth + translationFactor, translationFactor);    outlineArc.Size = barArc.Size = new Size(segmentWidth, size.Height);    outlineArc.Point = new Point(segmentWidth + translationFactor - 0.05, translationFactor);    RenderSegment();}

 

调用示例

我们定义了一个 RadialProgressBar 控件,底色是浅灰色,进度颜色是绿色,区间是 0~100,当前值是 29,进度条宽度是 20;从示例的运行图中可以印证这些数据。

 

 

总结

到这里我们就把 UWP Community Toolkit 中的 RadialProgressBar 控件的源代码实现过程和简单的调用示例讲解完成了,希望能对大家更好的理解和使用这个控件有所帮助;大家也可以基于简单的圆形进度条,扩展出更多中不同形状的进度条,例如矩形,实心圆形等等,欢迎大家多多交流,谢谢!

最后,再跟大家安利一下 UWPCommunityToolkit 的官方微博:大家可以通过微博关注最新动态。

衷心感谢 UWPCommunityToolkit 的作者们杰出的工作,Thank you so much, UWPCommunityToolkit authors!!!

转载地址:http://flktx.baihongyu.com/

你可能感兴趣的文章
[C] 判断目录 / 文件是否存在access()函数
查看>>
android中的broadcastReceiver
查看>>
日志收集系统-前奏
查看>>
apache php 60 503
查看>>
java - 线程1打印1-10,当线程打印到5后,线程2打印“hello”,然后线程1继续打印...
查看>>
创建扩展/自定义控件的方法
查看>>
闲聊javascript继承和原型
查看>>
js原生事件系统与坐标系统
查看>>
MongoDB学习系列(1)--入门介绍
查看>>
坐标转换convertRect
查看>>
canvas练习 - 七巧板绘制
查看>>
eas之去掉关闭eas页面时校验是否修改的提示
查看>>
第三次作业
查看>>
pwm的频率和占空比
查看>>
Electron 入门文档
查看>>
HDU-4565 So Easy! 公式化简
查看>>
希尔排序
查看>>
进程vs线程
查看>>
git设置用户名和邮箱
查看>>
接口测试——HttpClient工具的https请求、代理设置、请求头设置、获取状态码和响应头...
查看>>