ProgressBar.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using Avalonia.Controls.Primitives;
  4. namespace Avalonia.Controls
  5. {
  6. /// <summary>
  7. /// A control used to indicate the progress of an operation.
  8. /// </summary>
  9. public class ProgressBar : RangeBase
  10. {
  11. public static readonly StyledProperty<bool> IsIndeterminateProperty =
  12. AvaloniaProperty.Register<ProgressBar, bool>(nameof(IsIndeterminate));
  13. public static readonly StyledProperty<Orientation> OrientationProperty =
  14. AvaloniaProperty.Register<ProgressBar, Orientation>(nameof(Orientation), Orientation.Horizontal);
  15. private static readonly DirectProperty<ProgressBar, double> IndeterminateStartingOffsetProperty =
  16. AvaloniaProperty.RegisterDirect<ProgressBar, double>(
  17. nameof(IndeterminateStartingOffset),
  18. p => p.IndeterminateStartingOffset,
  19. (p, o) => p.IndeterminateStartingOffset = o);
  20. private static readonly DirectProperty<ProgressBar, double> IndeterminateEndingOffsetProperty =
  21. AvaloniaProperty.RegisterDirect<ProgressBar, double>(
  22. nameof(IndeterminateEndingOffset),
  23. p => p.IndeterminateEndingOffset,
  24. (p, o) => p.IndeterminateEndingOffset = o);
  25. private Border _indicator;
  26. static ProgressBar()
  27. {
  28. PseudoClass(OrientationProperty, o => o == Avalonia.Controls.Orientation.Vertical, ":vertical");
  29. PseudoClass(OrientationProperty, o => o == Avalonia.Controls.Orientation.Horizontal, ":horizontal");
  30. PseudoClass(IsIndeterminateProperty, ":indeterminate");
  31. ValueProperty.Changed.AddClassHandler<ProgressBar>(x => x.ValueChanged);
  32. }
  33. public bool IsIndeterminate
  34. {
  35. get => GetValue(IsIndeterminateProperty);
  36. set => SetValue(IsIndeterminateProperty, value);
  37. }
  38. public Orientation Orientation
  39. {
  40. get => GetValue(OrientationProperty);
  41. set => SetValue(OrientationProperty, value);
  42. }
  43. private double _indeterminateStartingOffset;
  44. private double IndeterminateStartingOffset
  45. {
  46. get => _indeterminateStartingOffset;
  47. set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value);
  48. }
  49. private double _indeterminateEndingOffset;
  50. private double IndeterminateEndingOffset
  51. {
  52. get => _indeterminateEndingOffset;
  53. set => SetAndRaise(IndeterminateEndingOffsetProperty, ref _indeterminateEndingOffset, value);
  54. }
  55. /// <inheritdoc/>
  56. protected override Size ArrangeOverride(Size finalSize)
  57. {
  58. UpdateIndicator(finalSize);
  59. return base.ArrangeOverride(finalSize);
  60. }
  61. /// <inheritdoc/>
  62. protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
  63. {
  64. _indicator = e.NameScope.Get<Border>("PART_Indicator");
  65. UpdateIndicator(Bounds.Size);
  66. }
  67. private void UpdateIndicator(Size bounds)
  68. {
  69. if (_indicator != null)
  70. {
  71. if (IsIndeterminate)
  72. {
  73. if (Orientation == Orientation.Horizontal)
  74. {
  75. var width = bounds.Width / 5.0;
  76. IndeterminateStartingOffset = -width;
  77. _indicator.Width = width;
  78. IndeterminateEndingOffset = bounds.Width;
  79. }
  80. else
  81. {
  82. var height = bounds.Height / 5.0;
  83. IndeterminateStartingOffset = -bounds.Height;
  84. _indicator.Height = height;
  85. IndeterminateEndingOffset = height;
  86. }
  87. }
  88. else
  89. {
  90. double percent = Maximum == Minimum ? 1.0 : (Value - Minimum) / (Maximum - Minimum);
  91. if (Orientation == Orientation.Horizontal)
  92. _indicator.Width = bounds.Width * percent;
  93. else
  94. _indicator.Height = bounds.Height * percent;
  95. }
  96. }
  97. }
  98. private void ValueChanged(AvaloniaPropertyChangedEventArgs e)
  99. {
  100. UpdateIndicator(Bounds.Size);
  101. }
  102. }
  103. }