diff --git a/samples/ControlCatalog/Pages/SliderPage.xaml b/samples/ControlCatalog/Pages/SliderPage.xaml
index c6f5521e60..ea31ed0050 100644
--- a/samples/ControlCatalog/Pages/SliderPage.xaml
+++ b/samples/ControlCatalog/Pages/SliderPage.xaml
@@ -6,11 +6,22 @@
A control that lets the user select from a range of values by moving a Thumb control along a Track.
-
+
+
+
+
TickPlacementProperty =
AvaloniaProperty.Register(nameof(TickPlacement), 0d);
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty> TicksProperty =
+ TickBar.TicksProperty.AddOwner();
+
// Slider required parts
private bool _isDragging = false;
private Track _track;
@@ -83,7 +90,8 @@ namespace Avalonia.Controls
PressedMixin.Attach();
OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
Thumb.DragStartedEvent.AddClassHandler((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
- Thumb.DragCompletedEvent.AddClassHandler((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble);
+ Thumb.DragCompletedEvent.AddClassHandler((x, e) => x.OnThumbDragCompleted(e),
+ RoutingStrategies.Bubble);
}
///
@@ -94,6 +102,15 @@ namespace Avalonia.Controls
UpdatePseudoClasses(Orientation);
}
+ ///
+ /// Defines the ticks to be drawn on the tick bar.
+ ///
+ public AvaloniaList Ticks
+ {
+ get => GetValue(TicksProperty);
+ set => SetValue(TicksProperty, value);
+ }
+
///
/// Gets or sets the orientation of a .
///
@@ -240,19 +257,50 @@ namespace Avalonia.Controls
/// Value that want to snap to closest Tick.
private double SnapToTick(double value)
{
- var previous = Minimum;
- var next = Maximum;
-
- if (TickFrequency > 0.0)
+ if (IsSnapToTickEnabled)
{
- previous = Minimum + (Math.Round((value - Minimum) / TickFrequency) * TickFrequency);
- next = Math.Min(Maximum, previous + TickFrequency);
+ double previous = Minimum;
+ double next = Maximum;
+
+ // This property is rarely set so let's try to avoid the GetValue
+ var ticks = Ticks;
+
+ // If ticks collection is available, use it.
+ // Note that ticks may be unsorted.
+ if ((ticks != null) && (ticks.Count > 0))
+ {
+ for (int i = 0; i < ticks.Count; i++)
+ {
+ double tick = ticks[i];
+ if (MathUtilities.AreClose(tick, value))
+ {
+ return value;
+ }
+
+ if (MathUtilities.LessThan(tick, value) && MathUtilities.GreaterThan(tick, previous))
+ {
+ previous = tick;
+ }
+ else if (MathUtilities.GreaterThan(tick, value) && MathUtilities.LessThan(tick, next))
+ {
+ next = tick;
+ }
+ }
+ }
+ else if (MathUtilities.GreaterThan(TickFrequency, 0.0))
+ {
+ previous = Minimum + (Math.Round(((value - Minimum) / TickFrequency)) * TickFrequency);
+ next = Math.Min(Maximum, previous + TickFrequency);
+ }
+
+ // Choose the closest value between previous and next. If tie, snap to 'next'.
+ value = MathUtilities.GreaterThanOrClose(value, (previous + next) * 0.5) ? next : previous;
}
- // Choose the closest value between previous and next. If tie, snap to 'next'.
- return MathUtilities.GreaterThanOrClose(value, (previous + next) * 0.5) ? next : previous;
+ return value;
}
+
private void UpdatePseudoClasses(Orientation o)
{
PseudoClasses.Set(":vertical", o == Orientation.Vertical);
diff --git a/src/Avalonia.Controls/TickBar.cs b/src/Avalonia.Controls/TickBar.cs
index 16e063beb3..22145d8742 100644
--- a/src/Avalonia.Controls/TickBar.cs
+++ b/src/Avalonia.Controls/TickBar.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using Avalonia.Controls.Primitives;
-using Avalonia.Data;
-using Avalonia.Data.Converters;
+using Avalonia.Collections;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Utilities;
@@ -135,15 +131,15 @@ namespace Avalonia.Controls
///
/// Defines the property.
///
- public static readonly StyledProperty> TicksProperty =
- AvaloniaProperty.Register>(nameof(Ticks));
+ public static readonly StyledProperty> TicksProperty =
+ AvaloniaProperty.Register>(nameof(Ticks));
///
/// The Ticks property contains collection of value of type Double which
/// are the logical positions use to draw the ticks.
/// The property value is a .
///
- public List Ticks
+ public AvaloniaList Ticks
{
get { return GetValue(TicksProperty); }
set { SetValue(TicksProperty, value); }
diff --git a/src/Avalonia.Themes.Default/Slider.xaml b/src/Avalonia.Themes.Default/Slider.xaml
index 1d48a946fc..ba4b1ee998 100644
--- a/src/Avalonia.Themes.Default/Slider.xaml
+++ b/src/Avalonia.Themes.Default/Slider.xaml
@@ -87,7 +87,10 @@
-
+
+
diff --git a/src/Avalonia.Themes.Fluent/Slider.xaml b/src/Avalonia.Themes.Fluent/Slider.xaml
index 539c448e0f..099c2000b8 100644
--- a/src/Avalonia.Themes.Fluent/Slider.xaml
+++ b/src/Avalonia.Themes.Fluent/Slider.xaml
@@ -182,6 +182,7 @@