Zum Inhalt
Kuonen.UI

SplitButton

Knöpfe mit Klappe: der Teilknopf löst mit dem Hauptteil aus und öffnet mit dem Pfeil ein Menü oder freien Inhalt (Farbfelder), der umschaltbare Teilknopf schaltet mit dem Hauptteil um, der DropDownButton öffnet seine Klappe beim Klick. Alt+Pfeil runter und F4 öffnen, Esc schliesst.

Vorführung: SplitButtonVorführung: SplitButton

KXAML

SplitButtonSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.SplitButtonVorfuehrung"
            Spacing="8">
  <TextBlock Text="Teilknopf mit Menü und mit freiem Inhalt" FontWeight="SemiBold" />
  <SplitButton Content="Einfügen" Click="Einfuegen_Click">
    <SplitButton.Flyout>
      <ContextMenu>
        <MenuItem Header="Nur Text" Click="Eintrag_Click" />
        <MenuItem Header="Mit Format" Click="Eintrag_Click" />
      </ContextMenu>
    </SplitButton.Flyout>
  </SplitButton>
  <!-- Die Farbfelder setzt das Code-Behind (eine Wahl meldet und schliesst die Klappe). -->
  <SplitButton x:Name="Farbe" Content="Schriftfarbe" Click="Farbe_Click" />
  <TextBlock Text="Umschaltbar" FontWeight="SemiBold" />
  <ToggleSplitButton x:Name="Aufzaehlung" Content="Aufzählung" IsCheckedChanged="Aufzaehlung_IsCheckedChanged">
    <ToggleSplitButton.Flyout>
      <ContextMenu>
        <MenuItem Header="Punkte" Click="Eintrag_Click" />
        <MenuItem Header="Zahlen" Click="Eintrag_Click" />
      </ContextMenu>
    </ToggleSplitButton.Flyout>
  </ToggleSplitButton>
  <TextBlock Text="Knopf mit Klappe" FontWeight="SemiBold" />
  <DropDownButton Content="Exportieren">
    <DropDownButton.Flyout>
      <ContextMenu>
        <MenuItem Header="PDF" Click="Eintrag_Click" />
        <MenuItem Header="Bild" Click="Eintrag_Click" />
      </ContextMenu>
    </DropDownButton.Flyout>
  </DropDownButton>
  <TextBlock x:Name="Meldung" Text="Bereit." />
</StackPanel>
SplitButtonSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;

namespace Kuonen.UI.Galerie.Seiten;

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

/// <summary>KXAML-Fassung der SplitButton-Seite: der Baum steht in SplitButtonSeite.kxaml, hier die Farbfelder und das Verhalten.</summary>
public sealed partial class SplitButtonVorfuehrung
{
    public SplitButtonVorfuehrung()
    {
        InitializeComponent();
        Farbe.Flyout = SplitButtonSeite.Farbfelder(Farbe, Meldung);
    }

    private void Einfuegen_Click(object? sender, RoutedEventArgs e) => Meldung.Text = "Eingefügt.";

    private void Farbe_Click(object? sender, RoutedEventArgs e) => Meldung.Text = "Schriftfarbe angewendet.";

    private void Aufzaehlung_IsCheckedChanged(object? sender, EventArgs e) => Meldung.Text = Aufzaehlung.IsChecked ? "Aufzählung an." : "Aufzählung aus.";

    private void Eintrag_Click(object? sender, RoutedEventArgs e) => Meldung.Text = SplitButtonSeite.Gewaehlt(sender);
}

C#

SplitButtonSeite.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="SplitButton"/>, <see cref="ToggleSplitButton"/> und <see cref="DropDownButton"/>.</summary>
public sealed partial class SplitButtonSeite : GalerieSeite
{
    public override string Titel => "SplitButton";

    public override string Beschreibung =>
        "Knöpfe mit Klappe: der Teilknopf löst mit dem Hauptteil aus und öffnet mit dem Pfeil ein Menü oder freien Inhalt (Farbfelder), der umschaltbare "
        + "Teilknopf schaltet mit dem Hauptteil um, der DropDownButton öffnet seine Klappe beim Klick. Alt+Pfeil runter und F4 öffnen, Esc schliesst.";

    public override string Stichworte => "Teilknopf Klappe Menü Flyout Schaltfläche SplitButton ToggleSplitButton DropDownButton IsChecked Click";

    public override string Datei => nameof(SplitButtonSeite);

    /// <summary>Die Farben der Schriftfarbe (Name, Wert), gleich in beiden Fassungen.</summary>
    internal static readonly (string Name, Color Farbe)[] Farben =
    [
        ("Rot", Color.FromRgb(0xC4, 0x2B, 0x1C)), ("Grün", Color.FromRgb(0x10, 0x7C, 0x10)), ("Blau", Color.FromRgb(0x00, 0x5F, 0xB8)), ("Schwarz", Color.FromRgb(0, 0, 0)),
    ];

    // Ein Farbfeld: ein Knopf mit einem Quadrat in der Farbe, benannt für den Bildschirmleser.
    internal static Button Farbfeld(string name, Color farbe)
    {
        var knopf = new Button { Content = new Border { Width = 18, Height = 18, Background = new SolidColorBrush(farbe) }, Padding = new Thickness(4) };
        knopf.Automation.Name = name;
        return knopf;
    }

    // Die Farbfelder in einer Reihe; die Wahl meldet und schliesst die Klappe.
    internal static StackPanel Farbfelder(SplitButton knopf, TextBlock meldung)
    {
        var reihe = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 4 };
        foreach (var (name, farbe) in Farben)
        {
            var feld = Farbfeld(name, farbe);
            feld.Click += (_, _) =>
            {
                meldung.Text = $"Schriftfarbe: {name}";
                knopf.SchliesseKlappe();
            };
            reihe.Children.Add(feld);
        }
        return reihe;
    }

    internal static string Gewaehlt(object? eintrag) => $"Gewählt: {(eintrag as MenuItem)?.Header}";

    private static ContextMenu Menue(TextBlock meldung, params string[] eintraege)
    {
        var menue = new ContextMenu();
        foreach (var text in eintraege)
        {
            var eintrag = new MenuItem { Header = text };
            eintrag.Click += (s, _) => meldung.Text = Gewaehlt(s);
            menue.Items.Add(eintrag);
        }
        return menue;
    }

    public override UIElement Baue()
    {
        var meldung = new TextBlock { Text = "Bereit." };
        var einfuegen = new SplitButton { Content = "Einfügen", Flyout = Menue(meldung, "Nur Text", "Mit Format") };
        einfuegen.Click += (_, _) => meldung.Text = "Eingefügt.";
        var farbe = new SplitButton { Content = "Schriftfarbe" };
        farbe.Flyout = Farbfelder(farbe, meldung);
        farbe.Click += (_, _) => meldung.Text = "Schriftfarbe angewendet.";
        var aufzaehlung = new ToggleSplitButton { Content = "Aufzählung", Flyout = Menue(meldung, "Punkte", "Zahlen") };
        aufzaehlung.IsCheckedChanged += (_, _) => meldung.Text = aufzaehlung.IsChecked ? "Aufzählung an." : "Aufzählung aus.";
        var exportieren = new DropDownButton { Content = "Exportieren", Flyout = Menue(meldung, "PDF", "Bild") };
        return new StackPanel
        {
            Spacing = 8,
            Children =
            {
                new TextBlock { Text = "Teilknopf mit Menü und mit freiem Inhalt", FontWeight = 600 },
                einfuegen,
                farbe,
                new TextBlock { Text = "Umschaltbar", FontWeight = 600 },
                aufzaehlung,
                new TextBlock { Text = "Knopf mit Klappe", FontWeight = 600 },
                exportieren,
                meldung,
            },
        };
    }
}