WPF 圆形进度条,带文字显示

6 篇文章 0 订阅
1 篇文章 0 订阅

WPF 在UI设计时常常需要圆型进度条如下图: (代码都上手敲出来的,喜欢的点个赞)

 

前台代码如下:

<UserControl x:Class="CircularProgressBar"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="150" d:DesignWidth="150">
    <Grid Name="layout" Height="{Binding RelativeSource={RelativeSource Self},Path=Width}">
        <Ellipse Width="{Binding ElementName=layout,Path=ActualWidth}"
                 Height="{Binding RelativeSource={RelativeSource Self},Path=Width}"
                 StrokeThickness="8"
                 Stroke="{Binding BackColor,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}" 
                 Name="backEllipse">
            <Ellipse.Effect>
                <DropShadowEffect ShadowDepth="0" Direction="0" Color="White" BlurRadius="5" />
            </Ellipse.Effect>
        </Ellipse>
        <Path Name="path" StrokeStartLineCap="Round" StrokeEndLineCap="Round"
              Stroke="{Binding ForeColor,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}" 
              StrokeThickness="6"/>
        <Viewbox Margin="14">
            <TextBlock  VerticalAlignment="Center" 
                        HorizontalAlignment="Center" 
                        Foreground="{Binding RelativeSource={RelativeSource Self},Path=Foreground}"
                        Text="{Binding Value,StringFormat={}{0:F1} %, RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}"  
                        >               
            </TextBlock>
        </Viewbox>
    </Grid>
</UserControl>

后台需要添加一些依赖怪属性,同时需要对给定的值做验证:

public partial class CircularProgressBar : UserControl
    {
        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set
            {
                SetValue(ValueProperty, value);
            }
        }
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(0.0, new PropertyChangedCallback(OnPropertyChanged)));

        public Brush BackColor
        {
            get { return (Brush)GetValue(BackColorProperty); }
            set { SetValue(BackColorProperty, value); }
        }
        public static readonly DependencyProperty BackColorProperty =
            DependencyProperty.Register("BackColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(Brushes.LightGray));

        public Brush ForeColor
        {
            get { return (Brush)GetValue(ForeColorProperty); }
            set { SetValue(ForeColorProperty, value); }
        }
        public static readonly DependencyProperty ForeColorProperty =
            DependencyProperty.Register("ForeColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(Brushes.Orange));

        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as CircularProgressBar).Value = Math.Min(100d, (d as CircularProgressBar).Value);//数据较验
           (d as CircularProgressBar).UpdateValue();
        }

        public CircularProgressBar()
        {
            InitializeComponent();

            this.SizeChanged += CircularProgressBar_SizeChanged;
        }

        private void CircularProgressBar_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.UpdateValue();
        }

通过Path画圆弧计算方法如下:

        private void UpdateValue()
        {
            this.layout.Width = Math.Min(this.RenderSize.Width, this.RenderSize.Height);
            this.layout.Height = Math.Min(this.RenderSize.Width, this.RenderSize.Height);
            double radius = Math.Min(this.RenderSize.Width, this.RenderSize.Height) / 2;
            if (radius <= 0) return;

            double newX = 0.0, newY = 0.0;
            newX = radius + (radius - 3) * Math.Cos((this.Value % 100.0 * 3.6 - 90) * Math.PI / 180);
            newY = radius + (radius - 3) * Math.Sin((this.Value % 100.0 * 3.6 - 90) * Math.PI / 180);

            string pathDataStr = "M{0} 3A{3} {3} 0 {4} 1 {1} {2}";
            pathDataStr = string.Format(pathDataStr,
                radius + 0.01,
                newX,
                newY,
                radius - 3,
                this.Value < 50 ? 0 : 1);
            var converter = TypeDescriptor.GetConverter(typeof(Geometry));
            this.path.Data = (Geometry)converter.ConvertFrom(pathDataStr);

        }
    }

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值