You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin Forms Slider控件中显示刻度标记

Got it! The default Xamarin.Forms Slider doesn’t come with built-in tick marks, but we can add this feature using custom renderers for both Android and iOS. Let’s walk through the implementation step by step:

Adding Tick Marks to Xamarin.Forms Slider (Android & iOS)

First, let's update your shared XAML to add a bindable property for the number of ticks (fits nicely with your existing MVVM setup):

<!-- Don't forget to add the namespace reference for your attached property -->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.YourPage">

    <Slider x:Name="slider" 
            HorizontalOptions="FillAndExpand" 
            Maximum="{Binding Maximum}" 
            Minimum="{Binding Minimum}" 
            local:SliderWithTicks.TickCount="{Binding TickCount}" />
</ContentPage>

Next, create an attached property in your shared project to hold the tick count value:

using Xamarin.Forms;

namespace YourAppNamespace
{
    public static class SliderWithTicks
    {
        public static readonly BindableProperty TickCountProperty =
            BindableProperty.CreateAttached(
                "TickCount", 
                typeof(int), 
                typeof(SliderWithTicks), 
                0,
                propertyChanged: OnTickCountChanged);

        public static int GetTickCount(BindableObject view)
        {
            return (int)view.GetValue(TickCountProperty);
        }

        public static void SetTickCount(BindableObject view, int value)
        {
            view.SetValue(TickCountProperty, value);
        }

        private static void OnTickCountChanged(BindableObject bindable, object oldValue, object newValue)
        {
            // Trigger renderer update when tick count changes
        }
    }
}

Android Custom Renderer

Create this renderer in your Android project to render ticks using the native SeekBar:

using Android.Content;
using Android.Widget;
using YourAppNamespace;
using YourAppNamespace.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(Slider), typeof(TickSliderRenderer))]
namespace YourAppNamespace.Droid
{
    public class TickSliderRenderer : SliderRenderer
    {
        public TickSliderRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
        {
            base.OnElementChanged(e);

            if (Control != null && e.NewElement != null)
            {
                UpdateTicks();
            }
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == SliderWithTicks.TickCountProperty.PropertyName ||
                e.PropertyName == Slider.MaximumProperty.PropertyName ||
                e.PropertyName == Slider.MinimumProperty.PropertyName)
            {
                UpdateTicks();
            }
        }

        private void UpdateTicks()
        {
            var tickCount = SliderWithTicks.GetTickCount(Element);
            if (tickCount <= 0) return;

            var seekBar = Control as SeekBar;
            // Use a built-in dot drawable or replace with your custom drawable from Resources/drawable
            seekBar.SetTickMarks(Android.Resource.Drawable.Dot);
            // NumTicks requires Android API 24+; for older versions, manually draw ticks
            seekBar.NumTicks = tickCount;
        }
    }
}

Note: If you need to support Android versions below API 24, you’ll need to manually draw ticks on a custom canvas instead of using NumTicks.

iOS Custom Renderer

Create this renderer in your iOS project to draw ticks directly on the native UISlider:

using CoreGraphics;
using YourAppNamespace;
using YourAppNamespace.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(Slider), typeof(TickSliderRenderer))]
namespace YourAppNamespace.iOS
{
    public class TickSliderRenderer : SliderRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
        {
            base.OnElementChanged(e);

            if (Control != null && e.NewElement != null)
            {
                DrawTicks();
            }
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == SliderWithTicks.TickCountProperty.PropertyName ||
                e.PropertyName == Slider.MaximumProperty.PropertyName ||
                e.PropertyName == Slider.MinimumProperty.PropertyName)
            {
                DrawTicks();
            }
        }

        private void DrawTicks()
        {
            var tickCount = SliderWithTicks.GetTickCount(Element);
            if (tickCount <= 0) return;

            // Remove existing ticks first
            Control.Subviews.OfType<UIView>().Where(v => v.Tag == 100).ToList().ForEach(v => v.RemoveFromSuperview());

            var sliderFrame = Control.Frame;
            var tickWidth = 2f;
            var tickHeight = 12f;
            var tickColor = UIColor.Gray;

            // Calculate spacing between each tick
            var tickSpacing = sliderFrame.Width / (tickCount - 1);

            for (int i = 0; i < tickCount; i++)
            {
                var tickFrame = new CGRect(
                    x: i * tickSpacing - tickWidth / 2,
                    y: sliderFrame.Height / 2 - tickHeight / 2,
                    width: tickWidth,
                    height: tickHeight);

                var tickView = new UIView(tickFrame);
                tickView.BackgroundColor = tickColor;
                tickView.Tag = 100; // Tag to identify our custom tick views
                Control.AddSubview(tickView);
                Control.SendSubviewToBack(tickView);
            }
        }
    }
}

Wire It Up in Your ViewModel

In your view model (make sure it implements INotifyPropertyChanged), add a TickCount property calculated based on your step value:

private int _tickCount;
public int TickCount
{
    get => _tickCount;
    set
    {
        _tickCount = value;
        OnPropertyChanged();
    }
}

// Example initialization: if min=0, max=10, step=1, tick count is 11
TickCount = (int)((Maximum - Minimum) / StepValue) + 1;

You can customize the tick appearance (color, size, shape) by adjusting the renderer code to match your app's design.

内容的提问来源于stack exchange,提问作者Mamta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:03:16