WPF中自带有长条形的进度条,大部分场景都算适用,但是仍然有一部分空间小的场景不太合适,此时我们想到安卓上常用的环形进度条,美观,又不占空间。

那么WPF中的环形进度条控件在哪呢?

很遗憾,自带组件中没有,这需要我们自己绘制。

环形进度条的核心在于根据百分比绘制弧形长度,在WPF中,PathGeometry可以绘制复杂形状,其中ArcSegment专门用于画弧形。

示例工程直接下载:https://download.csdn.net/download/u010875635/10791096

示例动画:

ArcSegment的弧形有几个重要参数,起点(一般在PathFigure中设置,ArcSegment属于PathFigure一部分)、两个半径是否优势弧(大于180度为优势弧)、终点旋转角度等。

我们根据角度百分比计算弧长终点,由于弧长虽然是线性增长,但对应的终点X、Y坐标并非是线性变化,我们需要区分4个象限来计算终点。

我们将弧形放置在一个方形的Grid中,半边长为R,设置弧形进度条的粗细为x,设置弧形半径为r(r要小于R-x),起始点坐标为 (leftStart, topStart)

一、第一象限终点计算

第一象限终点坐标为:X = leftStart + r*cos(α);  Y = topStart + r*sin(α);

二、第二象限终点计算

第二象限终点坐标为:X = leftStart + r*cos(α);  Y = topStart + r + r*sin(α);

三、第三象限终点计算

第三象限终点坐标为:X = leftStart  - r*sin(α);  Y = topStart + r + r*cos(α);

四、第四象限终点计算

第四象限终点坐标为:X = leftStart  - r*cos(α);  Y = topStart + r - r*sin(α);

注意100%时,终点与起点不要重合,最好偏移极小数值(太大弧形不好看),然后闭合图形,否则无法组合成圆。

详细代码如下:

一、自定义控件

前台:

<UserControl x:Class="BeatfanControls.ProcessBars.CycleProcessBar1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:BeatfanControls.ProcessBars"mc:Ignorable="d" ><Viewbox><Grid Width="34" Height="34"><Path Name="myCycleProcessBar1" Data="M17,3 A14,14 0 0 1 16,3 " Stroke="Green" StrokeThickness="3" Height="34" Width="34" VerticalAlignment="Center" HorizontalAlignment="Center"></Path><Label Name="lbValue" Content="50%" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="9" /></Grid></Viewbox>
</UserControl>

后台:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace BeatfanControls.ProcessBars
{/// <summary>/// CycleProcessBar1.xaml 的交互逻辑/// </summary>public partial class CycleProcessBar1 : UserControl{public CycleProcessBar1(){InitializeComponent();}public double CurrentValue1{set { SetValue(value); }}/// <summary>/// 设置百分百,输入小数,自动乘100/// </summary>/// <param name="percentValue"></param>private void SetValue(double percentValue){/*****************************************方形矩阵边长为34,半长为17环形半径为14,所以距离边框3个像素环形描边3个像素******************************************/double angel = percentValue * 360; //角度double radius = 14; //环形半径//起始点double leftStart = 17;double topStart = 3;//结束点double endLeft = 0;double endTop = 0;//数字显示lbValue.Content = (percentValue*100).ToString("0") + "%";/************************************************ 整个环形进度条使用Path来绘制,采用三角函数来计算* 环形根据角度来分别绘制,以90度划分,方便计算比例***********************************************/bool isLagreCircle = false; //是否优势弧,即大于180度的弧形//小于90度if (angel <= 90){/*******************   ** * ra* * * * * * * * **********************/double ra = (90 - angel) * Math.PI / 180; //弧度endLeft = leftStart + Math.Cos(ra) * radius; //余弦横坐标endTop = topStart + radius - Math.Sin(ra) * radius; //正弦纵坐标}else if (angel <= 180){/*******************  * * * * * * * * * ** * ra*  **   *******************/double ra = (angel - 90) * Math.PI / 180; //弧度endLeft = leftStart + Math.Cos(ra) * radius; //余弦横坐标endTop = topStart + radius + Math.Sin(ra) * radius;//正弦纵坐标}else if (angel <= 270){/*******************  * * * * * * * * * ** **ra**   *******************/isLagreCircle = true; //优势弧double ra = (angel - 180) * Math.PI / 180;endLeft = leftStart - Math.Sin(ra) * radius;endTop = topStart + radius + Math.Cos(ra) * radius;}else if (angel < 360){/******************   **  *  ra * * * * * * * * * * **********************/isLagreCircle = true; //优势弧double ra = (angel - 270) * Math.PI / 180;endLeft = leftStart - Math.Cos(ra) * radius;endTop = topStart + radius - Math.Sin(ra) * radius;}else{isLagreCircle = true; //优势弧endLeft = leftStart-0.001; //不与起点在同一点,避免重叠绘制出非环形endTop = topStart;}Point arcEndPt = new Point(endLeft, endTop); //结束点Size arcSize = new Size(radius, radius);SweepDirection direction = SweepDirection.Clockwise; //顺时针弧形//弧形ArcSegment arcsegment = new ArcSegment(arcEndPt, arcSize, 0, isLagreCircle, direction, true);//形状集合PathSegmentCollection pathsegmentCollection = new PathSegmentCollection();pathsegmentCollection.Add(arcsegment);//路径描述PathFigure pathFigure = new PathFigure();pathFigure.StartPoint = new Point(leftStart, topStart); //起始地址pathFigure.Segments = pathsegmentCollection;//路径描述集合PathFigureCollection pathFigureCollection = new PathFigureCollection();pathFigureCollection.Add(pathFigure);//复杂形状PathGeometry pathGeometry = new PathGeometry();pathGeometry.Figures = pathFigureCollection;//Data赋值myCycleProcessBar1.Data = pathGeometry;//达到100%则闭合整个if (angel == 360)myCycleProcessBar1.Data = Geometry.Parse(myCycleProcessBar1.Data.ToString() + " z");}}
}

二、调用:

前台:

<Window x:Class="CircleProgressBar.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:CircleProgressBar"xmlns:MyProgress="clr-namespace:BeatfanControls.ProcessBars"mc:Ignorable="d" Closing="Window_Closing"Title="环形进度条" Height="350" Width="525"><Grid ><Grid.RowDefinitions><RowDefinition Height="50*"/><RowDefinition Height="10*"/></Grid.RowDefinitions><MyProgress:CycleProcessBar1 x:Name="circleProgressBar" CurrentValue1="0.9" /><Button Name="btnStart" Content="开始" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click" /></Grid>
</Window>

后台:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace CircleProgressBar
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{/// <summary>/// 定时器/// </summary>private System.Windows.Threading.DispatcherTimer m_Timer1 = new System.Windows.Threading.DispatcherTimer();double m_Percent = 0;bool m_IsStart = false;public MainWindow(){InitializeComponent();m_Timer1.Interval = new TimeSpan(0, 0, 0,0,100);m_Timer1.Tick += M_Timer1_Tick;}private void M_Timer1_Tick(object sender, EventArgs e){m_Percent += 0.01;if (m_Percent > 1){m_Percent = 1;m_Timer1.Stop();m_IsStart = false;StartChange(m_IsStart);}circleProgressBar.CurrentValue1 = m_Percent;}/// <summary>/// UI变化/// </summary>/// <param name="bState"></param>private void StartChange(bool bState){if (bState)btnStart.Content = "停止";elsebtnStart.Content = "开始";}private void Button_Click(object sender, RoutedEventArgs e){if (m_IsStart){m_Timer1.Stop();m_IsStart = false;}else{m_Percent = 0;m_Timer1.Start();m_IsStart = true;}StartChange(m_IsStart);}private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e){m_Timer1.Stop();}}
}

【WPF】环形进度条相关推荐

  1. WPF自定义控件(教程含源码)-圆形进度条、环形进度条

    使用环形进度条显示用量百分比 控件效果如下 控件的关键属性如下: Background:控制背景圆环的原色. Stroke:控制进度圆环颜色.以及中间文本颜色. Value:进度百分比,double类 ...

  2. iOS通过CAShapeLayer和UIBezierPath画环形进度条

    UIBezierPath可以绘制矢量路径,而CAShapeLayer是Layer的子类,可以在屏幕进行绘制,本文主要思想是:CAShapeLayer按照UIBezierPath的矢量路径进行绘制. 效 ...

  3. 用svg实现一个环形进度条

    svg实现环形进度条需要用到的知识: 1.会使用path的d属性画一个圆环 //用svg的path元素的A命令画圆<pathd="M cx cym 0 -r a r r 0 1 0 0 ...

  4. js svg语音波动动画_SVG实现环形进度条的原理

    之前在项目中遇到一个环形进度条的需求,要求能实时更新进度,脑海中瞬间便蹦出css,svg,canvas3中方案,对于3种方案个人更偏向于svg,用法简单,代码量也很少,同时也便于实时控制.具体效果如下 ...

  5. canvas实现半圆环形进度条

    html部分 <canvas id="canvas" width="150" height="150"><p>抱歉, ...

  6. [Swift通天遁地]一、超级工具-(2)制作美观大方的环形进度条

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  7. 进度条上的小圆点怎么做_傲视网:【AE教程】如何制作环形进度条(第一讲)...

    原标题:傲视网:[AE教程]如何制作环形进度条(第一讲) 大家好,福利来啦!这里将分享如何制作环形进度条,教你如何从入门到精通学AE. 环形进度条是个特殊的动画,在旋转的基础上还要选择性地显示部分区域 ...

  8. iOS 自定义控件 progressView(环形进度条)

    转帖:http://blog.csdn.net/xiangzhang321/article/details/42688133 之前做项目的时候有用到环形进度条,先是在网上找了一下第三方控件,发现好用是 ...

  9. android canvas_Android 自定义View篇(七)实现环形进度条效果

    前言 Android 自定义 View 是高级进阶不可或缺的内容,日常工作中,经常会遇到产品.UI 设计出花里胡哨的界面.当系统自带的控件不能满足开发需求时,就只能自己动手撸一个效果. 本文就带自定义 ...

最新文章

  1. 如何正确运用计算机,如何正确使用电脑
  2. 我这么努力读个博士,难道只是为了进个高校拿5000每月的工资?
  3. mysql 生成xml 表头_Spring Boot + MySql + Mybatis generator 自动生成mapper/entity/xml文件
  4. NVIDIA ECCV18论文:超像素采样网络助力语义分割与光流估计(代码将开源)
  5. Python中的X[:,0]、X[:,1]、X[:,:,0]、X[:,:,1]、X[:,m:n]和X[:,:,m:n]
  6. bzoj 3504: [Cqoi2014]危桥(最大流)
  7. 汉仪股份通过注册:年营收2.2亿 谢立群控制公司35%股权
  8. py3Fdfs 修复几个bug
  9. kafka log4j日志级别修改,一天生成一个日志文件
  10. excel单元格内换行的方法
  11. html设置文字在背景图上,css如何实现文字在背景图片之上 css实现文字在背景图片之上代码...
  12. Sphinx使用方法
  13. 【循序渐进学运维】MySQL运维系列文章汇总
  14. DLNA使用设置教程
  15. Spring Data JPA/Hibernate 运行期动态模型、动态实体建表、动态字段查询的方式
  16. 杭电多校联赛2017年总结
  17. 关于字符、字符集、编码和Unicode
  18. 时序分析基本概念介绍ILM
  19. 全能IDE VsCode
  20. C语言/C++编程学习三种循环用法和区别

热门文章

  1. 项目管理 : 人力资源的项目管理
  2. CentOS Linux下用Nginx和Naxsi搭建Web应用防火墙
  3. 多屏幕ALV ZCL_ALV_MULTI
  4. 软件测试面试题:什么是α测试,β测试?
  5. thinkphp5.1+layui图片上传(前端部分.第二种)
  6. App灰度发布实现路径之小程序容器
  7. PIC单片机实现双字节无符号数的乘法
  8. 台式计算机硬盘1t,总结:4款1TB台式机硬盘如何选?_硬盘_内存硬盘评测-中关村在线...
  9. 关于猫叫、老鼠逃跑、人被惊醒的程序设计
  10. 关于STM32的CPU的使用率~裸机不带系统