WPF自定义控件(教程含源码)-圆形进度条、环形进度条
使用环形进度条显示用量百分比
控件效果如下
控件的关键属性如下:
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自定义控件(教程含源码)-圆形进度条、环形进度条相关推荐
- WPF自定义控件(教程含源码)-圆盘菜单
控件需求 圆盘菜单控件样式如下图所示 圆盘按钮 满足的功能需求 1.圆盘内的按钮,根据个数自动调整大小. 2.圆盘可以设置内径. 3.扇形按钮可以自定义"描边颜色"."描 ...
- SwiftUI 音乐和网络大全之网络音乐播放App支持iTunes搜索与播放(教程含源码)
实战需求 SwiftUI 音乐和网络大全之网络音乐播放App支持iTunes搜索与播放(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 实战代码 import SwiftUIstru ...
- SwiftUI 精品项目之完整MOOC幕课iOS项目 含服务端 轮播欢迎页面(教程含源码)
实战需求 SwiftUI 精品项目之完整MOOC幕课iOS项目 (教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 自动轮播 个性化注册界面 个人信息界面 带f ...
- Odoo16 教程含源码
Odoo16 教程含源码 Odoo16 开发教程 版本变化 模块开发步骤 源码 Odoo16 开发教程 Odoo 号称全球第一的开源ERP平台,除了提供一站式的企业应用开发解决方案,作为一个网站设计器 ...
- macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码)
实战需求 macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 支持剪切音频 支持复制音频 支持删除音频 支持un ...
- 抖音小程序基础之 目前提供哪些API(教程含源码)
抖音小程序基础之 目前提供哪些API(教程含源码) 小程序开发框架提供丰富的 字节跳动宿主 原生 API,可以方便的调起 字节跳动宿主 提供的能力,如获取系统信息等.详细介绍请参考 API 文档. 通 ...
- SwiftUI iOS 精品项目之每天收集的故事卡片(教程含源码)
实战需求 SwiftUI iOS 精品项目之每天收集的故事卡片(教程含源码) 每天收集的故事的卡片 本文价值与收获 看完本文后,您将能够作出下面的界面 核心功能 1.每天总共3个问题!选择一个您喜欢的 ...
- SwiftUI 界面大全之文本折叠书签动画组件3D(中文教程含源码)
实战需求 SwiftUI 界面大全之文本折叠书签动画组件3D(中文教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 基础知识 效果本身其实很简单,包括三件事: 图像的旋转 图像的垂直移 ...
- SwiftUI 绘图shape大全之 Teardrop水滴形状 (中文教程含源码)
实战需求 SwiftUI 绘图shape大全之 Teardrop水滴形状 (中文教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 基础知识 什么是Paths Paths主要用于绘制 ...
最新文章
- 在Visual Studio中启用对jquery等javascript框架的智能感知
- 瞬间教你学会使用java中list的retainAll方法
- 关于string类型的字符串是否以\0结尾
- getSystemService() in Android
- boost::safe_numerics模块实现数据类型下溢的测试程序
- Linux的SERVER_NAME 和HTTP_HOST
- 递归和分治的概念性的理解
- 理解Linux的overcommit memory
- C# DDOS攻击代码
- php java memcached_php-memcached详解
- 【每日算法Day 88】超越妹妹教你如何做这道排序题
- HPU--1392 分隔A+B
- 关于UIControl响应事件说明
- 浅析:通过自定义DSL实现一个序列号生成器
- [ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)
- 安装Ubuntu Core系统
- 陈如波律师:孙宇晨说自己“合法合规”站得住脚吗?
- OJ 2311 Problem A	Orange
- 《炬丰科技-半导体工艺》薄晶圆处理挑战和新兴解决方案
- 沧小海基于xilinx srio核的学习笔记之第三章 xilinx srio核介绍(一)结构介绍