Zum Inhalt
Kuonen.UI

SegmentedControl

Segmentierte Schaltflächen: die Ansicht als Einzelwahl (Pfeile bewegen und wählen, ein Tab-Halt), die Formatierung als Mehrfachwahl (Pfeile bewegen, Leertaste schaltet) und die Ausrichtung mit Symbolen, die einen Namen für den Bildschirmleser tragen. Mit dem Schieber von iOS und macOS wählt Ziehen.

Vorführung: SegmentedControlVorführung: SegmentedControl

KXAML

SegmentedControlSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.SegmentedControlVorfuehrung"
            Spacing="8">
  <TextBlock Text="Ansicht (Einzelwahl)" FontWeight="SemiBold" />
  <SegmentedControl x:Name="Ansicht" SelectionChanged="Ansicht_SelectionChanged">
    <SegmentedControlItem Content="Tag" IsSelected="True" />
    <SegmentedControlItem Content="Woche" />
    <SegmentedControlItem Content="Monat" />
  </SegmentedControl>
  <TextBlock Text="Format (Mehrfachwahl, nach Inhalt)" FontWeight="SemiBold" />
  <SegmentedControl x:Name="Format" SelectionMode="Multiple" IsSelectionRequired="False" IsEqualWidth="False" SelectionChanged="Format_SelectionChanged">
    <SegmentedControlItem Content="Fett" />
    <SegmentedControlItem Content="Kursiv" />
    <SegmentedControlItem Content="Unterstrichen" />
  </SegmentedControl>
  <!-- Die Symbol-Segmente (mit Namen für den Bildschirmleser) setzt das Code-Behind. -->
  <TextBlock Text="Ausrichtung (Symbole mit Namen)" FontWeight="SemiBold" />
  <SegmentedControl x:Name="Ausrichtung" SelectionChanged="Ausrichtung_SelectionChanged" />
  <TextBlock x:Name="Meldung" Text="Bereit." />
</StackPanel>
SegmentedControlSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;

namespace Kuonen.UI.Galerie.Seiten;

public sealed partial class SegmentedControlSeite
{
    protected override Func<UIElement>? KxamlFabrik => () => new SegmentedControlVorfuehrung();
}

/// <summary>KXAML-Fassung der SegmentedControl-Seite: der Baum steht in SegmentedControlSeite.kxaml, hier die Symbol-Segmente und das Verhalten.</summary>
public sealed partial class SegmentedControlVorfuehrung
{
    public SegmentedControlVorfuehrung()
    {
        InitializeComponent();
        foreach (var (name, symbol) in SegmentedControlSeite.Ausrichtungen) Ausrichtung.Items.Add(SegmentedControlSeite.Symbolsegment(name, symbol));
        Ausrichtung.SelectedIndex = 0;
        Meldung.Text = "Bereit."; // die Startwahl meldet nicht (wie in der C#-Fassung, die erst danach abonniert)
    }

    // Eine Wahl kann schon beim Aufbau melden (IsSelected im KXAML), bevor die Meldungszeile steht.
    private void Melde(string text)
    {
        if (Meldung is not null) Meldung.Text = text;
    }

    private void Ansicht_SelectionChanged(object sender, SelectionChangedEventArgs e) => Melde(SegmentedControlSeite.Gewaehlt("Ansicht", Ansicht));

    private void Format_SelectionChanged(object sender, SelectionChangedEventArgs e) => Melde(SegmentedControlSeite.Gewaehlt("Format", Format));

    private void Ausrichtung_SelectionChanged(object sender, SelectionChangedEventArgs e) => Melde(SegmentedControlSeite.Gewaehlt("Ausrichtung", Ausrichtung));
}

C#

SegmentedControlSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
using Kuonen.UI.Media;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: <see cref="SegmentedControl"/>.</summary>
public sealed partial class SegmentedControlSeite : GalerieSeite
{
    public override string Titel => "SegmentedControl";

    public override string Beschreibung =>
        "Segmentierte Schaltflächen: die Ansicht als Einzelwahl (Pfeile bewegen und wählen, ein Tab-Halt), die Formatierung als Mehrfachwahl (Pfeile bewegen, "
        + "Leertaste schaltet) und die Ausrichtung mit Symbolen, die einen Namen für den Bildschirmleser tragen. Mit dem Schieber von iOS und macOS wählt Ziehen.";

    public override string Stichworte => "Segmente Segmentiert Umschalter Auswahl Optionsgruppe SegmentedControl SegmentedControlItem IsEqualWidth IsSelectionRequired";

    public override string Datei => nameof(SegmentedControlSeite);

    internal static readonly string[] Ansichten = ["Tag", "Woche", "Monat"];

    internal static readonly string[] Formate = ["Fett", "Kursiv", "Unterstrichen"];

    internal static readonly (string Name, PathGeometry Symbol)[] Ausrichtungen =
    [
        ("Links", Symbole.ChevronLinks), ("Mitte", Symbole.Minus), ("Rechts", Symbole.ChevronRechts),
    ];

    // Die gewählten Segmente: der Text, bei einem Segment-Element dessen Inhalt oder Name.
    internal static string Gewaehlt(string was, SegmentedControl s)
    {
        if (s.SelectedItems.Count == 0) return $"{was}: keine";
        var namen = new string[s.SelectedItems.Count];
        for (int i = 0; i < namen.Length; i++)
            namen[i] = s.SelectedItems[i] switch
            {
                SegmentedControlItem { Content: string text } => text,
                SegmentedControlItem segment => segment.Automation.Name,
                var anderes => $"{anderes}",
            };
        return $"{was}: {string.Join(", ", namen)}";
    }

    // Segmente mit Text als eigene Elemente (wie in der KXAML-Fassung).
    private static SegmentedControl Segmente(string[] texte)
    {
        var segmente = new SegmentedControl();
        foreach (var text in texte) segmente.Items.Add(new SegmentedControlItem { Content = text });
        return segmente;
    }

    internal static SegmentedControlItem Symbolsegment(string name, PathGeometry symbol)
    {
        var segment = new SegmentedControlItem { Icon = symbol };
        segment.Automation.Name = name;
        return segment;
    }

    public override UIElement Baue()
    {
        var meldung = new TextBlock { Text = "Bereit." };
        var ansicht = Segmente(Ansichten);
        ((SegmentedControlItem)ansicht.Items[0]!).IsSelected = true; // wie IsSelected="True" in der KXAML-Fassung
        ansicht.SelectionChanged += (_, _) => meldung.Text = Gewaehlt("Ansicht", ansicht);
        var format = Segmente(Formate);
        format.SelectionMode = SelectionMode.Multiple;
        format.IsSelectionRequired = false;
        format.IsEqualWidth = false;
        format.SelectionChanged += (_, _) => meldung.Text = Gewaehlt("Format", format);
        var ausrichtung = new SegmentedControl();
        foreach (var (name, symbol) in Ausrichtungen) ausrichtung.Items.Add(Symbolsegment(name, symbol));
        ausrichtung.SelectedIndex = 0;
        ausrichtung.SelectionChanged += (_, _) => meldung.Text = Gewaehlt("Ausrichtung", ausrichtung);
        return new StackPanel
        {
            Spacing = 8,
            Children =
            {
                new TextBlock { Text = "Ansicht (Einzelwahl)", FontWeight = 600 },
                ansicht,
                new TextBlock { Text = "Format (Mehrfachwahl, nach Inhalt)", FontWeight = 600 },
                format,
                new TextBlock { Text = "Ausrichtung (Symbole mit Namen)", FontWeight = 600 },
                ausrichtung,
                meldung,
            },
        };
    }
}