WPF圈进度条 [英] WPF circle progress bar

查看:100
本文介绍了WPF圈进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用第一个圆圈替换常规的ProgressBar,并在论坛中单击搜索后找到了我想要的东西.

I want to replace the regular ProgressBar with circle one and after shot search here in the forum i found what i want.

CircularProgressBar.XAML

CircularProgressBar.XAML

<Grid>
    <Path x:Name="pathRoot" Stroke="{Binding SegmentColor, ElementName=userControl}" 
          StrokeThickness="{Binding StrokeThickness, ElementName=userControl}" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigureCollection>
                        <PathFigure x:Name="pathFigure">
                            <PathFigure.Segments>
                                <PathSegmentCollection>
                                    <ArcSegment x:Name="arcSegment" SweepDirection="Clockwise" />
                                </PathSegmentCollection>
                            </PathFigure.Segments>
                        </PathFigure>
                    </PathFigureCollection>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
    </Path>
</Grid>

CircularProgressBar.cs:

CircularProgressBar.cs:

public partial class CircularProgressBar : UserControl
{
    public CircularProgressBar()
    {
        InitializeComponent();
        Angle = (Percentage * 360) / 100;
        RenderArc();
    }

    public int Radius
    {
        get { return (int)GetValue(RadiusProperty); }
        set { SetValue(RadiusProperty, value); }
    }

    public Brush SegmentColor
    {
        get { return (Brush)GetValue(SegmentColorProperty); }
        set { SetValue(SegmentColorProperty, value); }
    }

    public int StrokeThickness
    {
        get { return (int)GetValue(StrokeThicknessProperty); }
        set { SetValue(StrokeThicknessProperty, value); }
    }

    public double Percentage
    {
        get { return (double)GetValue(PercentageProperty); }
        set { SetValue(PercentageProperty, value); }
    }

    public double Angle
    {
        get { return (double)GetValue(AngleProperty); }
        set { SetValue(AngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Percentage.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PercentageProperty =
        DependencyProperty.Register("Percentage", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(65d, new PropertyChangedCallback(OnPercentageChanged)));

    // Using a DependencyProperty as the backing store for StrokeThickness.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StrokeThicknessProperty =
        DependencyProperty.Register("StrokeThickness", typeof(int), typeof(CircularProgressBar), new PropertyMetadata(5, new PropertyChangedCallback(OnThicknessChanged)));

    // Using a DependencyProperty as the backing store for SegmentColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SegmentColorProperty =
        DependencyProperty.Register("SegmentColor", typeof(Brush), typeof(CircularProgressBar), new PropertyMetadata(new SolidColorBrush(Colors.Red), new PropertyChangedCallback(OnColorChanged)));

    // Using a DependencyProperty as the backing store for Radius.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty RadiusProperty =
        DependencyProperty.Register("Radius", typeof(int), typeof(CircularProgressBar), new PropertyMetadata(25, new PropertyChangedCallback(OnPropertyChanged)));

    // Using a DependencyProperty as the backing store for Angle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty AngleProperty =
        DependencyProperty.Register("Angle", typeof(double), typeof(CircularProgressBar), new PropertyMetadata(120d, new PropertyChangedCallback(OnPropertyChanged)));

    private static void OnColorChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        CircularProgressBar circle = sender as CircularProgressBar;
        circle.set_Color((SolidColorBrush)args.NewValue);
    }

    private static void OnThicknessChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        CircularProgressBar circle = sender as CircularProgressBar;
        circle.set_tick((int)args.NewValue);
    }

    private static void OnPercentageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        CircularProgressBar circle = sender as CircularProgressBar;
        if (circle.Percentage > 100) circle.Percentage = 100;
        circle.Angle = (circle.Percentage * 360) / 100;
    }

    private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        CircularProgressBar circle = sender as CircularProgressBar;
        circle.RenderArc();
    }

    public void set_tick(int n)
    {
        pathRoot.StrokeThickness = n;
    }

    public void set_Color(SolidColorBrush n)
    {
        pathRoot.Stroke = n;
    }

    public void RenderArc()
    {
        Point startPoint =  new Point(Radius, 0);
        Point endPoint = ComputeCartesianCoordinate(Angle, Radius);
        endPoint.X += Radius;
        endPoint.Y += Radius;

        pathRoot.Width = Radius * 2 + StrokeThickness;
        pathRoot.Height = Radius * 2 + StrokeThickness;
        pathRoot.Margin = new Thickness(StrokeThickness, StrokeThickness, 0, 0);

        bool largeArc = Angle > 180.0;

        Size outerArcSize = new Size(Radius, Radius);

        pathFigure.StartPoint = startPoint;

        if (startPoint.X == Math.Round(endPoint.X) && startPoint.Y == Math.Round(endPoint.Y))
            endPoint.X -= 0.01;

        arcSegment.Point = endPoint;
        arcSegment.Size = outerArcSize;
        arcSegment.IsLargeArc = largeArc;
    }

    private Point ComputeCartesianCoordinate(double angle, double radius)
    {
        // convert to radians
        double angleRad = (Math.PI / 180.0) * (angle - 90);

        double x = radius * Math.Cos(angleRad);
        double y = radius * Math.Sin(angleRad);

        return new Point(x, y);
    }
}

MainWindow.xaml:

MainWindow.xaml:

    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
              SegmentColor="#FF878889" StrokeThickness="25" Percentage="100" />
            <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
              Percentage="{Binding Value, ElementName=slider}" SegmentColor="#026873" StrokeThickness="25" />
        </Grid>
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </StackPanel>
    <Slider x:Name="slider" Grid.Row="1" Maximum="100" Value="60" />
</Grid>

结果:

http://s21.postimg.org/xymj8k4pz/image.png

因此,将相同的代码复制粘贴到我的解决方案中并运行后,我看到的只是Slider,而没有Circle Bar,这是我的代码:

So after copy paste the same code into my solution and running all i can see is only the Slider withou the Circle Bar, this is my code:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="530,303,114,303">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
         SegmentColor="#FF878889" StrokeThickness="8" Percentage="100" />
        <DesignInControl:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center"
         Percentage="{Binding Value, ElementName=slider}" SegmentColor="#026873" StrokeThickness="8" />
    </Grid>
</StackPanel>
<Slider x:Name="slider" Maximum="100" Value="20" Width="200" Margin="597,185,227,495" />

我做错什么了吗?

推荐答案

您可能错过了UserControl定义中的x:Name="userControl":

You probably missed x:Name="userControl" in the UserControl definition:

<UserControl x:Name="userControl" x:Class="DesignInControl.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">
    <Grid>
        <Path x:Name="pathRoot" Stroke="{Binding SegmentColor, ElementName=userControl}" StrokeThickness="{Binding StrokeThickness, ElementName=userControl}" HorizontalAlignment="Left" VerticalAlignment="Top">
            <Path.Data>
             ...

这篇关于WPF圈进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆