WPF自定义圆形百分比进度条

文章介绍了如何使用XAML和C#在WindowsPresentationFoundation(WPF)中创建一个可定制的环形进度条,包括界面代码的XML声明和后台处理百分比变化的方法。
摘要由CSDN通过智能技术生成

先看效果图

1.界面代码

<UserControl x:Class="LensAgingTest.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:LensAgingTest"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Viewbox>
            <Grid Width="34" Height="34">
                <Path Name="myCycleProcessBar" Data="M17,3 A14,14 0 1 0 17.001,3 " Stroke="LightGray" StrokeThickness="3" Height="34" Width="34" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                <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>
    </Grid>
</UserControl>

2.后台代码

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 LensAgingTest
{
    /// <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赋值
            //myCycleProcessBar.Data = pathGeometry;
            myCycleProcessBar1.Data = pathGeometry;
            //达到100%则闭合整个
            if (angel == 360)
                myCycleProcessBar1.Data = Geometry.Parse(myCycleProcessBar1.Data.ToString() + " z");
        }
    }
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF中,要重写一个圆形进度条,我们可以通过自定义一个继承自Button的新控件来实现。 首先,我们需要定义一个新的类,比如名为CircularProgressBar的控件。在这个类中,我们可以重写Button的外观和交互逻辑来实现圆形进度条的效果。 在重写的过程中,我们可以使用XAML来定义控件的外观。可以通过一个Border包裹一个Canvas元素来创建一个圆形进度条的底部背景。然后在这个Canvas中添加一个圆形Shape,比如Ellipse或者Path,来表示进度条的当前进度。 在类内部,我们可以定义一个依赖属性来控制进度条的当前进度。这个属性可以使用一个Double类型的值来表示进度的百分比。 为了实现进度条从0%到100%的动画效果,我们可以使用WPF的动画功能。可以使用DoubleAnimation来定义一个从0到100的动画,然后将这个动画应用到进度条的当前进度属性上。 最后,我们需要在类中定义一些方法来更新进度条的状态。比如,可以定义一个名为SetProgress的方法来设置进度条的当前进度。在这个方法中,我们可以将传入的进度值应用到进度条的当前进度属性上,然后触发动画效果。 综上所述,通过自定义一个继承自Button的新控件,我们可以重写WPF圆形进度条。在重写过程中,我们可以定义一个新的类来控制进度条的外观和交互逻辑,使用XAML定义控件的外观,使用依赖属性来控制进度条的当前进度,并使用动画来实现进度条从0%到100%的动画效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值