浏览代码

Snap thumb on custom ticks when they are set

Mihai Stan 5 年之前
父节点
当前提交
6561cb739a
共有 1 个文件被更改,包括 39 次插入8 次删除
  1. 39 8
      src/Avalonia.Controls/Slider.cs

+ 39 - 8
src/Avalonia.Controls/Slider.cs

@@ -257,19 +257,50 @@ namespace Avalonia.Controls
         /// <param name="value">Value that want to snap to closest Tick.</param>
         /// <param name="value">Value that want to snap to closest Tick.</param>
         private double SnapToTick(double value)
         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
+                List<double> 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)
         private void UpdatePseudoClasses(Orientation o)
         {
         {
             PseudoClasses.Set(":vertical", o == Orientation.Vertical);
             PseudoClasses.Set(":vertical", o == Orientation.Vertical);