ButtonSpinner
Drehfelder: ein ButtonSpinner um einen Text mit eigener Logik (Grösse S bis XL, die Knöpfe sperren an den Enden, wahlweise links), und DomainUpDown über Einträgen: Wochentage reihum (Wrap), Monate zum Tippen (ein Anfang wählt den ersten passenden), nur lesbar mit Buchstabensprung.


KXAML
ButtonSpinnerSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
x:Class="Kuonen.UI.Galerie.Seiten.ButtonSpinnerVorfuehrung"
Spacing="8">
<TextBlock Text="ButtonSpinner (Grösse)" FontWeight="SemiBold" />
<ButtonSpinner x:Name="Spinner" Spin="Spinner_Spin">
<TextBlock x:Name="Groesse" Text="M" Width="40" VerticalAlignment="Center" />
</ButtonSpinner>
<CheckBox Content="Knöpfe links" Checked="Links_Checked" Unchecked="Links_Unchecked" />
<TextBlock Text="Wochentag (reihum)" FontWeight="SemiBold" />
<!-- Die Einträge setzt das Code-Behind (dieselben Listen wie die C#-Fassung). -->
<DomainUpDown x:Name="Wochentag" Width="200" HorizontalAlignment="Left" Wrap="True" SelectedItemChanged="Wochentag_SelectedItemChanged" />
<TextBlock Text="Monat (tippen)" FontWeight="SemiBold" />
<DomainUpDown x:Name="Monat" Width="200" HorizontalAlignment="Left" SelectedItemChanged="Monat_SelectedItemChanged" />
<TextBlock Text="Nur lesbar (Buchstabe springt)" FontWeight="SemiBold" />
<DomainUpDown x:Name="Fest" Width="200" HorizontalAlignment="Left" ReadOnly="True" SelectedItemChanged="Fest_SelectedItemChanged" />
<TextBlock x:Name="Meldung" Text="Bereit." />
</StackPanel>ButtonSpinnerSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class ButtonSpinnerSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new ButtonSpinnerVorfuehrung();
}
/// <summary>KXAML-Fassung der ButtonSpinner-Seite: der Baum steht in ButtonSpinnerSeite.kxaml, hier die Einträge und das Verhalten.</summary>
public sealed partial class ButtonSpinnerVorfuehrung
{
private bool _bereit;
public ButtonSpinnerVorfuehrung()
{
InitializeComponent();
ButtonSpinnerSeite.Sperre(Spinner, 1);
ButtonSpinnerSeite.Fuelle(Wochentag, ButtonSpinnerSeite.Wochentage);
Wochentag.SelectedIndex = 0;
ButtonSpinnerSeite.Fuelle(Monat, ButtonSpinnerSeite.Monate);
ButtonSpinnerSeite.Fuelle(Fest, ButtonSpinnerSeite.Wochentage);
Fest.SelectedIndex = 0;
_bereit = true; // die Startwahl meldet nicht (wie in der C#-Fassung, die erst danach abonniert)
}
private void Melde(string text)
{
if (_bereit) Meldung.Text = text;
}
private void Spinner_Spin(object sender, SpinEventArgs e)
{
ButtonSpinnerSeite.Drehe(Spinner, Groesse, e);
Melde($"Grösse: {Groesse.Text}");
}
private void Links_Checked(object sender, RoutedEventArgs e) => Spinner.ButtonSpinnerLocation = Location.Left;
private void Links_Unchecked(object sender, RoutedEventArgs e) => Spinner.ButtonSpinnerLocation = Location.Right;
private void Wochentag_SelectedItemChanged(object? sender, EventArgs e) => Melde($"Tag: {Wochentag.SelectedItem}");
private void Monat_SelectedItemChanged(object? sender, EventArgs e) => Melde($"Monat: {Monat.SelectedItem}");
private void Fest_SelectedItemChanged(object? sender, EventArgs e) => Melde($"Nur lesbar: {Fest.SelectedItem}");
}C#
ButtonSpinnerSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: <see cref="ButtonSpinner"/> und <see cref="DomainUpDown"/>.</summary>
public sealed partial class ButtonSpinnerSeite : GalerieSeite
{
public override string Titel => "ButtonSpinner";
public override string Beschreibung =>
"Drehfelder: ein ButtonSpinner um einen Text mit eigener Logik (Grösse S bis XL, die Knöpfe sperren an den Enden, wahlweise links), und DomainUpDown "
+ "über Einträgen: Wochentage reihum (Wrap), Monate zum Tippen (ein Anfang wählt den ersten passenden), nur lesbar mit Buchstabensprung.";
public override string Stichworte => "Drehfeld Spinner Auf Ab Stepper Wochentag Liste ButtonSpinner DomainUpDown Spin ValidSpinDirection Wrap ReadOnly";
public override string Datei => nameof(ButtonSpinnerSeite);
internal static readonly string[] Groessen = ["S", "M", "L", "XL"];
internal static readonly string[] Wochentage = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"];
internal static readonly string[] Monate =
["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
// Die Grösse dreht im Text und sperrt die Richtung an den Enden.
internal static void Drehe(ButtonSpinner spinner, TextBlock text, SpinEventArgs e)
{
int i = Math.Max(Array.IndexOf(Groessen, text.Text), 0);
i = Math.Clamp(i + (e.Direction == SpinDirection.Increase ? 1 : -1), 0, Groessen.Length - 1);
text.Text = Groessen[i];
Sperre(spinner, i);
}
internal static void Sperre(ButtonSpinner spinner, int i) =>
spinner.ValidSpinDirection = (i < Groessen.Length - 1 ? ValidSpinDirections.Increase : ValidSpinDirections.None)
| (i > 0 ? ValidSpinDirections.Decrease : ValidSpinDirections.None);
internal static void Fuelle(DomainUpDown feld, string[] eintraege)
{
foreach (var e in eintraege) feld.Items.Add(e);
}
public override UIElement Baue()
{
var meldung = new TextBlock { Text = "Bereit." };
var groesse = new TextBlock { Text = "M", Width = 40, VerticalAlignment = VerticalAlignment.Center };
var spinner = new ButtonSpinner { Content = groesse };
Sperre(spinner, 1);
spinner.Spin += (_, e) =>
{
Drehe(spinner, groesse, e);
meldung.Text = $"Grösse: {groesse.Text}";
};
var links = new CheckBox { Content = "Knöpfe links" };
links.Checked += (_, _) => spinner.ButtonSpinnerLocation = Location.Left;
links.Unchecked += (_, _) => spinner.ButtonSpinnerLocation = Location.Right;
var tag = new DomainUpDown { Width = 200, HorizontalAlignment = HorizontalAlignment.Left, Wrap = true };
Fuelle(tag, Wochentage);
tag.SelectedIndex = 0;
tag.SelectedItemChanged += (_, _) => meldung.Text = $"Tag: {tag.SelectedItem}";
var monat = new DomainUpDown { Width = 200, HorizontalAlignment = HorizontalAlignment.Left };
Fuelle(monat, Monate);
monat.SelectedItemChanged += (_, _) => meldung.Text = $"Monat: {monat.SelectedItem}";
var fest = new DomainUpDown { Width = 200, HorizontalAlignment = HorizontalAlignment.Left, ReadOnly = true };
Fuelle(fest, Wochentage);
fest.SelectedIndex = 0;
fest.SelectedItemChanged += (_, _) => meldung.Text = $"Nur lesbar: {fest.SelectedItem}";
return new StackPanel
{
Spacing = 8,
Children =
{
new TextBlock { Text = "ButtonSpinner (Grösse)", FontWeight = 600 },
spinner,
links,
new TextBlock { Text = "Wochentag (reihum)", FontWeight = 600 },
tag,
new TextBlock { Text = "Monat (tippen)", FontWeight = 600 },
monat,
new TextBlock { Text = "Nur lesbar (Buchstabe springt)", FontWeight = 600 },
fest,
meldung,
},
};
}
}