using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using HandyControl.Data; using HandyControl.Expression.Shapes; namespace HandyControl.Controls; [TemplatePart(Name = IndicatorTemplateName, Type = typeof(Arc))] public class CircleProgressBar : RangeBase { private const string IndicatorTemplateName = "PART_Indicator"; public static readonly DependencyProperty ArcThicknessProperty = DependencyProperty.Register( nameof(ArcThickness), typeof(double), typeof(CircleProgressBar), new PropertyMetadata(ValueBoxes.Double0Box)); public static readonly DependencyProperty ShowTextProperty = DependencyProperty.Register( nameof(ShowText), typeof(bool), typeof(CircleProgressBar), new PropertyMetadata(ValueBoxes.TrueBox)); public static readonly DependencyProperty TextProperty = DependencyProperty.Register( nameof(Text), typeof(string), typeof(CircleProgressBar), new PropertyMetadata(default(string))); public static readonly DependencyProperty IsIndeterminateProperty = ProgressBar.IsIndeterminateProperty.AddOwner(typeof(CircleProgressBar), new FrameworkPropertyMetadata(ValueBoxes.FalseBox)); private Arc _indicator; static CircleProgressBar() { FocusableProperty.OverrideMetadata(typeof(CircleProgressBar), new FrameworkPropertyMetadata(ValueBoxes.FalseBox)); MaximumProperty.OverrideMetadata(typeof(CircleProgressBar), new FrameworkPropertyMetadata(ValueBoxes.Double100Box)); } public string Text { get => (string) GetValue(TextProperty); set => SetValue(TextProperty, value); } public bool ShowText { get => (bool) GetValue(ShowTextProperty); set => SetValue(ShowTextProperty, ValueBoxes.BooleanBox(value)); } public double ArcThickness { get => (double) GetValue(ArcThicknessProperty); set => SetValue(ArcThicknessProperty, value); } public bool IsIndeterminate { get => (bool) GetValue(IsIndeterminateProperty); set => SetValue(IsIndeterminateProperty, ValueBoxes.BooleanBox(value)); } private void SetProgressBarIndicatorAngle() { if (_indicator == null) return; var minimum = Minimum; var maximum = Maximum; var num = Value; _indicator.EndAngle = (maximum <= minimum ? 0 : (num - minimum) / (maximum - minimum)) * 360; } public override void OnApplyTemplate() { base.OnApplyTemplate(); _indicator = GetTemplateChild(IndicatorTemplateName) as Arc; if (_indicator != null) { _indicator.StartAngle = 0; _indicator.EndAngle = 0; } SetProgressBarIndicatorAngle(); } protected override void OnMinimumChanged(double oldMinimum, double newMinimum) { base.OnMinimumChanged(oldMinimum, newMinimum); SetProgressBarIndicatorAngle(); } protected override void OnMaximumChanged(double oldMaximum, double newMaximum) { base.OnMaximumChanged(oldMaximum, newMaximum); SetProgressBarIndicatorAngle(); } protected override void OnValueChanged(double oldValue, double newValue) { base.OnValueChanged(oldValue, newValue); SetProgressBarIndicatorAngle(); } }