WPF中利用Ellipse或Rectangle实现圆形进度条

效果如下
WPF中利用Ellipse或Rectangle实现圆形进度条_第1张图片
上面两个进度条,分别利用了Ellipse或Rectangle的StrokeThickness属性和StrokeDashArray属性,StrokeDashArray是设置边框长度,但要根据StrokeThickness的厚度进行相关于周长的转换。
转换函数如下

/// 
/// 计算进度条百分比
/// 
/// 百分比0-100
/// 圆角的度数
/// 控件边框厚度
/// 
public static DoubleCollection CalcProgress(double progress, double radius,double thickness)
{
    var r = radius - thickness / 2;
    var perimeter = 2 * Math.PI * r / thickness;
    var step = progress / 100 * perimeter;
    var result = new DoubleCollection() { step, 1000 };
    return result;
}

下面分别是Ellipse或Rectangle实现的圆形进度条的UI代码

<StackPanel Background="#4E59A4" Orientation="Horizontal">
	 <Grid Margin="50" Background="Transparent" Width="100" Height="100">
	     <Ellipse Stroke="Gray" StrokeThickness="12"/>
	     <Ellipse StrokeThickness="12" StrokeDashArray="{Binding ProcessValue}" RenderTransformOrigin="0.5,0.5">
	         <Ellipse.Stroke>
	             <LinearGradientBrush StartPoint="0.5,0.5" EndPoint="0,1">
	                 <GradientStop Offset="1" Color="#B7A227"/>
	                 <GradientStop Offset="0" Color="#0a9644"/>
	             </LinearGradientBrush>
	         </Ellipse.Stroke>
	         <Ellipse.Effect>
	             <DropShadowEffect BlurRadius="8" ShadowDepth="0" Opacity="1" Color="WhiteSmoke"/>
	         </Ellipse.Effect>
	         <Ellipse.RenderTransform>
	             <RotateTransform Angle="-90"/>
	         </Ellipse.RenderTransform>
	     </Ellipse>
	     <TextBlock Foreground="White" Text="{Binding ProcessNumber}" FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center">
	         <TextBlock.Effect>
	             <DropShadowEffect ShadowDepth="0" BlurRadius="6" Color="White"/>
	         </TextBlock.Effect>
	     </TextBlock>
	 </Grid>
	
	 <Grid Margin="50" Background="Transparent" Width="100" Height="100">
	     <Rectangle Width="100" Height="100" Stroke="LightGray" StrokeThickness="12" RadiusX="50" RadiusY="50"/>
	     <Rectangle Width="100" Height="100" StrokeThickness="12" RadiusX="50" RadiusY="50" StrokeDashCap="Round" StrokeDashArray="{Binding ProcessValue}"  RenderTransformOrigin="0.5,0.5">
	         <Rectangle.Stroke>
	             <LinearGradientBrush StartPoint="0.5,0.5" EndPoint="0,1">
	                 <GradientStop Offset="1" Color="#FFCD41"/>
	                 <GradientStop Offset="0" Color="#0a9644"/>
	             </LinearGradientBrush>
	         </Rectangle.Stroke>
	         <Rectangle.Effect>
	             <DropShadowEffect BlurRadius="8" ShadowDepth="0" Opacity="1" Color="WhiteSmoke"/>
	         </Rectangle.Effect>
	         <Rectangle.RenderTransform>
	             <RotateTransform Angle="90"/>
	         </Rectangle.RenderTransform>
	     </Rectangle>
	     <TextBlock Foreground="White" Text="{Binding ProcessNumber}" FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center">
	         <TextBlock.Effect>
	             <DropShadowEffect ShadowDepth="0" BlurRadius="6" Color="White"/>
	         </TextBlock.Effect>
	     </TextBlock>
	 </Grid>
	</StackPanel>

这里我们主要是绑定了一个ProcessValue对象给到Ellipse或Rectangle的StrokeDashArray属性,而ProcessValue对象是一个DoubleCollection类,它表示 System.Double 值的有序集合。最后我们在一个适当的地方更新ProcessValue的值即可。

Task.Run(() =>
{
    while (true)
    {
        Thread.Sleep(1000);
        Application.Current.Dispatcher.Invoke(() =>
        {
            double second = (DateTime.Now.Second * 100) / 60;
            ProcessValue = CalcHelper.CalcProgress(second, 50, 12);
            ProcessNumber = second + "%";
        });

    }
});

下面是两个绑定属性的定义

private DoubleCollection doubleCollection = new DoubleCollection() { 0, 1000 };
/// 
/// 圆形进度条数组
/// 
public DoubleCollection ProcessValue
{
    get { return doubleCollection; }
    set { doubleCollection = value;RaisePropertyChanged("ProcessValue"); }
}

private string processNumber;
/// 
/// 圆形进度条百分比值
/// 
public string ProcessNumber
{
    get { return processNumber; }
    set { processNumber = value; RaisePropertyChanged("ProcessNumber"); }
}

你可能感兴趣的:(WPF,wpf,microsoft,ui)