当前位置: 首页 > news >正文

WPF自定义控件之环形进度条

1.创建RingProgressBar类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;namespace CircularProgressBar
{public class RingProgressBar : FrameworkElement{/// <summary>/// 声明并注册一个依赖属性 Progress,用于控制进度条显示的百分比(0 ~ 100)。/// </summary>public static readonly DependencyProperty ProgressProperty =DependencyProperty.Register(nameof(Progress),                         // 属性名称typeof(double),                           // 属性类型typeof(RingProgressBar),                  // 所属类型new FrameworkPropertyMetadata(0.0,                                  // 默认值FrameworkPropertyMetadataOptions.AffectsRender // 当值变化时自动触发重绘));/// <summary>/// Progress 属性包装器,提供进度值的获取和设置。/// 设置时自动裁剪到 0~100 范围。/// </summary>public double Progress{get => (double)GetValue(ProgressProperty);set => SetValue(ProgressProperty, Math.Max(0, Math.Min(100, value)));}/// <summary>/// 重写 OnRender 方法,使用 DrawingContext 绘制控件外观。/// </summary>protected override void OnRender(DrawingContext dc){double width = ActualWidth;double height = ActualHeight;// 根据控件尺寸计算圆环半径,保留 5 像素边距double radius = Math.Min(width, height) / 2 - 5;// 圆心位置Point center = new Point(width / 2, height / 2);// 1. 绘制背景圆环(灰色圆环)dc.DrawEllipse(null,                                       // 无填充new Pen(Brushes.LightGray, 10),             // 使用浅灰色画笔,宽度10center,                                     // 圆心radius, radius                              // 水平半径 & 垂直半径);// 2. 计算进度角度(转换为 0~360)double angle = Progress / 100 * 360;// 3. 将角度转换为弧度,-90 是为了从正上方开始绘制double radians = (angle - 90) * Math.PI / 180;// 4. 圆环起点:圆顶部Point startPoint = new Point(center.X, center.Y - radius);// 5. 计算终点:根据弧度计算 X/YPoint endPoint = new Point(center.X + radius * Math.Cos(radians),center.Y + radius * Math.Sin(radians));// 6. 判断是否需要绘制大角度弧(超过180度)bool isLargeArc = angle > 180;// 7. 创建一个弧线段,从 startPoint 到 endPoint,构成圆环的一部分PathFigure figure = new PathFigure(startPoint,                                // 弧线起点new[]{new ArcSegment(endPoint,                          // 弧线终点new Size(radius, radius),          // 弧线的X/Y半径0,                                 // 旋转角度isLargeArc,                        // 是否为大角度弧线SweepDirection.Clockwise,          // 顺时针方向true                               // 弧线是否可见(用于裁剪,一般设为 true))},false                                       // 图形是否闭合(环形不闭合));// 8. 创建 PathGeometry 对象用于绘制PathGeometry geometry = new PathGeometry();geometry.Figures.Add(figure);// 9. 绘制进度圆环(蓝色)dc.DrawGeometry(null,                                      // 无填充new Pen(Brushes.SteelBlue, 10),            // 钢蓝色画笔,宽度10geometry                                   // 绘制路径);}/// <summary>/// Measure 阶段:建议大小为 100x100。/// </summary>protected override Size MeasureOverride(Size availableSize) => new Size(100, 100);/// <summary>/// Arrange 阶段:直接接受布局系统给予的最终大小。/// </summary>protected override Size ArrangeOverride(Size finalSize) => finalSize;}}

2.在XAML中使用
我们需要在 XAML 文件中使用该控件,需要在窗体或页面里引入命名空间

<Window x:Class="CircularProgressBar.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:CircularProgressBar"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Grid.RowDefinitions><RowDefinition /></Grid.RowDefinitions><!--  // 自定义控件 - 预览主体部分  注意地址不一定是local  要看RingProgressBar类放在哪里 //  --><local:RingProgressBar x:Name="ringProgress"Width="200"Height="200"HorizontalAlignment="Center"VerticalAlignment="Center"Progress="0" /><TextBlock x:Name="ShowProgressValue"HorizontalAlignment="Center"VerticalAlignment="Center"FontSize="24"Foreground="#d3d3d3" /><Button Width="100"Height="30"Margin="0,50"HorizontalAlignment="Center"VerticalAlignment="Bottom"Content="🚀 执行"Click="Button_Click" /></Grid>
</Window>

3.MainWindow.cs代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
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 CircularProgressBar
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private async void Button_Click(object sender, RoutedEventArgs e){for (int i = 0; i < 101; i++){ringProgress.Progress = i;ShowProgressValue.Text = ringProgress.Progress.ToString() + "%";await RelayAsync(100);}}private async Task RelayAsync(int milliseconds, CancellationToken cancellationToken = default){if (milliseconds < 0){milliseconds = 100;}try{await Task.Delay(milliseconds, cancellationToken);}catch (TaskCanceledException){// 取消操作}}}
}

http://www.dtcms.com/a/465591.html

相关文章:

  • 深度学习入门(一)——从神经元到损失函数,一步步理解前向传播(下)
  • php网站怎么做伪静态织梦模板网站好吗
  • 电脑所有可用的网络接口
  • 宁波网站设计推广培训班呼和浩特做网站的
  • TensorFlow深度学习实战(40)——图神经网络(GNN)
  • 水库安全保障:单北斗GNSS变形监测系统的应用与维护探讨
  • Spring中Bean 的生命周期
  • 【C++】智能指针介绍
  • 利用腾讯混元大模型搭建Cherry Studio自有知识库,打造“智能第二大脑”
  • 咸阳做网站的公司有哪些电商卖货平台有哪些
  • 浏阳网站建设卷云网络做网页的it网站
  • 广东省省考备考(第一百二十天10.10)——资料分析、判断推理(强化训练)
  • 常用的C++压测框架
  • 强化学习之父 Richard Sutton :大模型是死路一条
  • 【YOLO 模型入门】(1)一文读懂 YOLO:从核心概念到检测原理
  • redis消息队列
  • AI任务相关解决方案21-一种基于大语言模型、多智能体协作平台MCP、Agent、RAG技术的项目投标智能化系统与方法
  • 做一个能注册用户的网站深圳优化网站公司
  • 哈尔滨seo建站怎么用wordpress建立自己的网站
  • Frigate - IP 摄像头开源程序实时目标检测 NVR
  • Ubuntu系统使用指南
  • BERT文本分类超参数优化实战:从13小时到83秒的性能飞跃
  • 传输层协议之TCP协议
  • k8s中实现pod热加载
  • 医疗网站建设中心百度做个网站要多少钱
  • 万盛网站建设公司视频网站制作
  • H618-内核驱动的第一个hello world
  • IEEE内期刊论文爬取
  • 网站设计创意wordpress实现图片幻灯展示效果
  • docker部署安装milvus(向量数据库)、配置依赖etcd和MinIO