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

Android分段控件色调修改及C#后端动态操作SegmentedControl问询

Hey there! Let's break down how to handle both selecting segments programmatically and customizing the color of your cross-platform SegmentedControl for iOS and Android.

1. Programmatically Selecting a Segment in C#

To enable programmatic selection, you'll need to add a bindable property to your SegmentedControl class to track the selected index (or selected option), then update the native platform controls to reflect this state.

Step 1: Add Selected Index/Option Bindable Properties

Extend your existing SegmentedControl class with these properties:

public class SegmentedControl : View, IViewContainer<SegmentedControlOption>
{
    // ... Your existing code ...

    // Track selected index
    public static readonly BindableProperty SelectedIndexProperty =
        BindableProperty.Create(nameof(SelectedIndex), typeof(int), typeof(SegmentedControl), -1,
            propertyChanged: OnSelectedIndexChanged);

    public int SelectedIndex
    {
        get => (int)GetValue(SelectedIndexProperty);
        set => SetValue(SelectedIndexProperty, value);
    }

    // Track selected option (optional, for direct option binding)
    public static readonly BindableProperty SelectedOptionProperty =
        BindableProperty.Create(nameof(SelectedOption), typeof(SegmentedControlOption), typeof(SegmentedControl), null,
            propertyChanged: OnSelectedOptionChanged);

    public SegmentedControlOption SelectedOption
    {
        get => (SegmentedControlOption)GetValue(SelectedOptionProperty);
        set => SetValue(SelectedOptionProperty, value);
    }

    // Handle index change
    private static void OnSelectedIndexChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (SegmentedControl)bindable;
        if (control.Children != null && control.SelectedIndex >= 0 && control.SelectedIndex < control.Children.Count)
        {
            control.OnSelectedIndexChanged((int)oldValue, (int)newValue);
        }
    }

    // Handle option change
    private static void OnSelectedOptionChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (SegmentedControl)bindable;
        if (newValue is SegmentedControlOption option)
        {
            var index = control.Children.IndexOf(option);
            if (index != -1 && control.SelectedIndex != index)
            {
                control.SelectedIndex = index;
            }
        }
        else
        {
            control.SelectedIndex = -1;
        }
    }

    // Event for external listeners
    public event EventHandler<SelectedIndexChangedEventArgs> SelectedIndexChanged;

    protected virtual void OnSelectedIndexChanged(int oldIndex, int newIndex)
    {
        SelectedIndexChanged?.Invoke(this, new SelectedIndexChangedEventArgs(oldIndex, newIndex));
    }
}

// Helper event args class
public class SelectedIndexChangedEventArgs : EventArgs
{
    public int OldIndex { get; }
    public int NewIndex { get; }

    public SelectedIndexChangedEventArgs(int oldIndex, int newIndex)
    {
        OldIndex = oldIndex;
        NewIndex = newIndex;
    }
}

Step 2: Update Native Renderers

You need to sync the selected index with the native platform controls:

iOS Renderer

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    base.OnElementPropertyChanged(sender, e);
    if (e.PropertyName == SegmentedControl.SelectedIndexProperty.PropertyName)
    {
        var nativeControl = (UISegmentedControl)Control;
        var segmentedControl = (SegmentedControl)Element;
        if (segmentedControl.SelectedIndex >= 0 && segmentedControl.SelectedIndex < nativeControl.NumberOfSegments)
        {
            nativeControl.SelectedSegment = segmentedControl.SelectedIndex;
        }
    }
}

Android Renderer

Assuming you're using a RadioGroup-based implementation:

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    base.OnElementPropertyChanged(sender, e);
    if (e.PropertyName == SegmentedControl.SelectedIndexProperty.PropertyName)
    {
        var segmentedControl = (SegmentedControl)Element;
        if (segmentedControl.SelectedIndex >= 0 && segmentedControl.SelectedIndex < Control.ChildCount)
        {
            var selectedButton = (RadioButton)Control.GetChildAt(segmentedControl.SelectedIndex);
            selectedButton.Checked = true;
        }
    }
}

Step 3: Use Programmatic Selection

Now you can select segments in your C# code like this:

// Select the first segment (index 0)
mySegmentedControl.SelectedIndex = 0;

// Or select a specific option directly
var targetOption = mySegmentedControl.Children.FirstOrDefault(o => o.Text == "Settings");
mySegmentedControl.SelectedOption = targetOption;

2. Customizing the Control's Color

You already started with the TintColorProperty—let's complete the implementation to apply this color to native controls.

Step 1: Finalize the TintColor Property

Update your existing property with change handling:

public static readonly BindableProperty TintColorProperty =
    BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(SegmentedControl), Colors.Blue,
        propertyChanged: OnTintColorChanged);

public Color TintColor
{
    get => (Color)GetValue(TintColorProperty);
    set => SetValue(TintColorProperty, value);
}

private static void OnTintColorChanged(BindableObject bindable, object oldValue, object newValue)
{
    var control = (SegmentedControl)bindable;
    control.OnTintColorChanged((Color)oldValue, (Color)newValue);
}

protected virtual void OnTintColorChanged(Color oldColor, Color newColor)
{
    // Optional: Trigger event if external code needs to react to color changes
}

Step 2: Apply Color to Native Controls

iOS Renderer

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    base.OnElementPropertyChanged(sender, e);
    if (e.PropertyName == SegmentedControl.TintColorProperty.PropertyName)
    {
        var nativeControl = (UISegmentedControl)Control;
        var segmentedControl = (SegmentedControl)Element;
        var uiColor = segmentedControl.TintColor.ToUIColor();
        
        // Set tint color for selected segment border/text
        nativeControl.TintColor = uiColor;
        // Optional: Customize selected text color
        nativeControl.SetTitleTextAttributes(new UITextAttributes { TextColor = uiColor }, UIControlState.Selected);
    }
}

Android Renderer

For a custom segmented control using RadioButtons:

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    base.OnElementPropertyChanged(sender, e);
    if (e.PropertyName == SegmentedControl.TintColorProperty.PropertyName)
    {
        var segmentedControl = (SegmentedControl)Element;
        var androidColor = segmentedControl.TintColor.ToAndroid();
        
        for (int i = 0; i < Control.ChildCount; i++)
        {
            var button = (RadioButton)Control.GetChildAt(i);
            // Set text color for selected/unselected states
            button.SetTextColor(new ColorStateList(
                new int[][] { new int[] { Android.Resource.Attribute.StateChecked }, new int[0] },
                new int[] { androidColor, Android.Graphics.Color.Gray }
            ));
            
            // Set rounded background for selected/unselected states
            var shape = new GradientDrawable();
            shape.SetCornerRadius(8); // Adjust radius to match your design
            shape.SetColor(new ColorStateList(
                new int[][] { new int[] { Android.Resource.Attribute.StateChecked }, new int[0] },
                new int[] { androidColor, Android.Graphics.Color.Transparent }
            ));
            button.Background = shape;
        }
    }
}

Step 3: Modify Color Programmatically

Change the color in your C# code like this:

// Set to a solid color
mySegmentedControl.TintColor = Colors.Orange;

// Or use a hex color
mySegmentedControl.TintColor = Color.FromHex("#2ECC71");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:25:25