使用环形进度条显示用量百分比

控件效果如下

控件的关键属性如下:

Background:控制背景圆环的原色。

Stroke:控制进度圆环颜色、以及中间文本颜色。

Value:进度百分比,double类型,进度0~1.

控件前端xaml模板

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WPFCustomControl.Controls"><!--圆弧绑定转换,根据控件属性转换圆弧--><local:RingProgressArcConverter x:Key="ringProgressArcConverter" /><!--文本显示转换--><local:RingProgressValueConverter x:Key="ringProgressValueConverter" /><ControlTemplate x:Key="RingProgress_Template" TargetType="local:RingProgress"><Grid><Path StrokeThickness="{TemplateBinding StrokeThickness}" Stroke="{TemplateBinding Background}" StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="rootRing" ><Path.Data><MultiBinding Converter="{StaticResource ringProgressArcConverter}"><Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /><Binding Path="ActualHeight" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /><Binding Path="StrokeThickness" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /></MultiBinding></Path.Data></Path><Path StrokeThickness="{TemplateBinding StrokeThickness}" Stroke="{TemplateBinding Stroke}" StrokeEndLineCap="Round" StrokeStartLineCap="Round"HorizontalAlignment="Center" VerticalAlignment="Center"Width="{Binding ElementName=rootRing, Path=ActualWidth}"Height="{Binding ElementName=rootRing, Path=ActualHeight}"><Path.Data><MultiBinding Converter="{StaticResource ringProgressArcConverter}"><Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /><Binding Path="ActualHeight" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /><Binding Path="StrokeThickness" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /><Binding Path="Value" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=local:RingProgress}" /></MultiBinding></Path.Data></Path><TextBlock Foreground="{TemplateBinding Stroke}" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Value, Converter={StaticResource ringProgressValueConverter}}"/></Grid></ControlTemplate><!--设置 RingProgress 的默认样式--><Style TargetType="local:RingProgress"><Setter Property="Template" Value="{StaticResource RingProgress_Template}" /><Setter Property="Background" Value="#D2D2D2" /></Style>
</ResourceDictionary>

控件后台代码:

    public partial class RingProgress : RangeBase{static RingProgress(){DefaultStyleKeyProperty.OverrideMetadata(typeof(RingProgress), new FrameworkPropertyMetadata(typeof(RingProgress)));}#region StrokeThickness 圆环描边宽度public static readonly DependencyProperty StrokeThicknessProperty =DependencyProperty.Register("StrokeThickness", typeof(double), typeof(RingProgress), new PropertyMetadata(10d));public double StrokeThickness{get { return (double)GetValue(StrokeThicknessProperty); }set { SetValue(StrokeThicknessProperty, value); }}#endregion#region Stroke 圆环描边颜色public static readonly DependencyProperty StrokeProperty =DependencyProperty.Register("Stroke", typeof(Brush), typeof(RingProgress), new PropertyMetadata(Brushes.Red));public Brush Stroke{get { return (Brush)GetValue(StrokeProperty); }set { SetValue(StrokeProperty, value); }}#endregion}internal class RingProgressArcConverter : IMultiValueConverter{// 注意,因为这里使用Path绘制圆环, 所以要把描边宽度大小考虑进去. 所有点的x、y偏移 半个描边宽度public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture){double value;if (values[0] is double width&& values[1] is double height&& width > 0 && height>0&& values[2] is double storkeWidth){width -= storkeWidth;height -= storkeWidth;value = values.Length == 4 ? System.Convert.ToDouble(values[3]) : 1d;if (value == 0) return "";var startAngle = -90d;var endAngle = Math.Min(value * 360 -90 , 269);var radius = Math.Min(width, height) * 0.5;var start = startAngle.AngleToPoint(radius, storkeWidth * 0.5);var end = endAngle.AngleToPoint(radius, storkeWidth * 0.5);var dataStr = $"M {start.X},{start.Y} A {radius},{radius} 0 {(endAngle - startAngle >= 180 ? 1 : 0)} 1 {end.X},{end.Y}";var converter = TypeDescriptor.GetConverter(typeof(Geometry));return (Geometry)converter.ConvertFrom(dataStr);}else{return "";}}public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture){throw new NotImplementedException();}}internal class RingProgressValueConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){if (value is double v){return $"{v * 100}%";}else{return 0;}}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){throw new NotImplementedException();}}internal static class RingProgressExtension{/// <summary>/// 角度转为弧度/// </summary>/// <param name="a"></param>/// <returns></returns>public static double AngleToArc(this double a){return Math.PI * a / 180;}/// <summary>/// 角度及半径计算坐标点位置/// </summary>/// <param name="a"></param>/// <param name="radius"></param>/// <param name="offset"></param>/// <returns></returns>public static Point AngleToPoint(this double a, double radius, double offset = 0){return new Point(Math.Cos(a.AngleToArc()) * radius + radius + offset, Math.Sin(a.AngleToArc()) * radius + radius + offset);}}

使用示例

        <UniformGrid Rows="2" Columns="2"><c:RingProgress Value="0.1" Margin="5" Stroke="#393D49" Background="#31BDEC" /><c:RingProgress Value="0.3" Margin="5" Stroke="Red" Background="#C2C2C2"/><c:RingProgress Value="0.5" Margin="5" Stroke="Red" Background="#C2C2C2"/><c:RingProgress Value="0.7" Margin="5" Stroke="Red" Background="#C2C2C2"/></UniformGrid>

有问题的请评论去留言。

WPF自定义控件(教程含源码)-圆形进度条、环形进度条相关推荐

  1. WPF自定义控件(教程含源码)-圆盘菜单

    控件需求 圆盘菜单控件样式如下图所示 圆盘按钮 满足的功能需求 1.圆盘内的按钮,根据个数自动调整大小. 2.圆盘可以设置内径. 3.扇形按钮可以自定义"描边颜色"."描 ...

  2. SwiftUI 音乐和网络大全之网络音乐播放App支持iTunes搜索与播放(教程含源码)

    实战需求 SwiftUI 音乐和网络大全之网络音乐播放App支持iTunes搜索与播放(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 实战代码 import SwiftUIstru ...

  3. SwiftUI 精品项目之完整MOOC幕课iOS项目 含服务端 轮播欢迎页面(教程含源码)

    实战需求 SwiftUI 精品项目之完整MOOC幕课iOS项目 (教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 自动轮播 个性化注册界面 个人信息界面 带f ...

  4. Odoo16 教程含源码

    Odoo16 教程含源码 Odoo16 开发教程 版本变化 模块开发步骤 源码 Odoo16 开发教程 Odoo 号称全球第一的开源ERP平台,除了提供一站式的企业应用开发解决方案,作为一个网站设计器 ...

  5. macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码)

    实战需求 macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 支持剪切音频 支持复制音频 支持删除音频 支持un ...

  6. 抖音小程序基础之 目前提供哪些API(教程含源码)

    抖音小程序基础之 目前提供哪些API(教程含源码) 小程序开发框架提供丰富的 字节跳动宿主 原生 API,可以方便的调起 字节跳动宿主 提供的能力,如获取系统信息等.详细介绍请参考 API 文档. 通 ...

  7. SwiftUI iOS 精品项目之每天收集的故事卡片(教程含源码)

    实战需求 SwiftUI iOS 精品项目之每天收集的故事卡片(教程含源码) 每天收集的故事的卡片 本文价值与收获 看完本文后,您将能够作出下面的界面 核心功能 1.每天总共3个问题!选择一个您喜欢的 ...

  8. SwiftUI 界面大全之文本折叠书签动画组件3D(中文教程含源码)

    实战需求 SwiftUI 界面大全之文本折叠书签动画组件3D(中文教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 基础知识 效果本身其实很简单,包括三件事: 图像的旋转 图像的垂直移 ...

  9. SwiftUI 绘图shape大全之 Teardrop水滴形状 (中文教程含源码)

    实战需求 SwiftUI 绘图shape大全之 Teardrop水滴形状 (中文教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 基础知识 ​ 什么是Paths Paths主要用于绘制 ...

最新文章

  1. 在Visual Studio中启用对jquery等javascript框架的智能感知
  2. 瞬间教你学会使用java中list的retainAll方法
  3. 关于string类型的字符串是否以\0结尾
  4. getSystemService() in Android
  5. boost::safe_numerics模块实现数据类型下溢的测试程序
  6. Linux的SERVER_NAME 和HTTP_HOST
  7. 递归和分治的概念性的理解
  8. 理解Linux的overcommit memory
  9. C# DDOS攻击代码
  10. php java memcached_php-memcached详解
  11. 【每日算法Day 88】超越妹妹教你如何做这道排序题
  12. HPU--1392 分隔A+B
  13. 关于UIControl响应事件说明
  14. 浅析:通过自定义DSL实现一个序列号生成器
  15. [ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)
  16. 安装Ubuntu Core系统
  17. 陈如波律师:孙宇晨说自己“合法合规”站得住脚吗?
  18. OJ 2311 Problem A Orange
  19. 《炬丰科技-半导体工艺》薄晶圆处理挑战和新兴解决方案
  20. 沧小海基于xilinx srio核的学习笔记之第三章 xilinx srio核介绍(一)结构介绍

热门文章

  1. 【C语言】scanf,getchar,getch函数详解
  2. Windows7安装IE11步骤和中文安装包超简单
  3. 基于机器学习的5G精准营销模型
  4. 完美主义者适合当程序员?
  5. 实习生被拒绝的N个理由
  6. Spring Boot内置Tomcat设置超时时间
  7. sympy高斯光束模型
  8. c语言中fcntl.h函数库,fcntl函数的使用详解
  9. StringUtils.split用法
  10. ws2_32.dll和wsock32.dll