berry wer
berry wer

Reputation: 647

Add several user controls with different properties over my application

I found this implementation of CircularProgressBar. This is the .cs file:

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(1));

    // 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)));

    // 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(105, 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 OnPercentageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        CircularProgressBar circle = sender as CircularProgressBar;
        circle.Angle = (circle.Percentage * 270) / 100;
    }

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

    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);
    }
}

Because i didn't want complete Circular but only half one i have changed this:

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

And put the value of 180 instead of 360. Now i want to add the same control in my application but this time i want this Circular to be in complete Circle so my question is how can i do that ?

Upvotes: 1

Views: 52

Answers (1)

Mike Eason
Mike Eason

Reputation: 9713

You can create another dependency property which will act as the mode for the circular progress bar.

    public enum Modes
    {
        Full = 360,
        Half = 180
    }

    public Modes CircularMode
    {
        get { return (Modes)GetValue(CircularModeProperty); }
        set { SetValue(CircularModeProperty, value); }
    }

    public static readonly DependencyProperty CircularModeProperty =
        DependencyProperty.Register("CircularMode", typeof(Modes), typeof(CircularProgressBar), new PropertyMetadata(Modes.Full));

You can then use this value in your calculation:

circle.Angle = (circle.Percentage * (int)circle.CircularMode) / 100;

Usage:

<xyz:CircularProgressBar CircularMode="Half" ... 

Or

<xyz:CircularProgressBar CircularMode="Full" ... 

Note: 'xyz' is just an example namespace definition, this will very likely be different in your application.

Upvotes: 1

Related Questions