ComboBox
Ein Klappfeld: zeigt die gewählte Möglichkeit, die Liste klappt darunter auf. Der Fokus bleibt im Feld; die Pfeile heben in der offenen Liste eine Stelle hervor, Eingabe übernimmt, Escape schliesst. Getippte Buchstaben springen zum passenden Eintrag. Editierbar (IsEditable) ist die Box ein Textfeld: Tippen ergänzt den ersten passenden Ort markiert und wählt ihn.


KXAML
ComboBoxSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
xmlns:local="using:Kuonen.UI.Galerie.Seiten"
x:Class="Kuonen.UI.Galerie.Seiten.ComboBoxVorfuehrung"
Spacing="12">
<TextBlock Text="Farbe" FontWeight="SemiBold" />
<!-- Erst die Einträge, dann die Wahl, dann die Handler: der Startzustand meldet nichts. -->
<ComboBox x:Name="Farbe" Width="180" ItemsSource="{x:Static local:ComboBoxVorfuehrung.Farben}" SelectedIndex="4"
SelectionChanged="Farbe_SelectionChanged" DropDownOpened="Farbe_DropDownOpened" DropDownClosed="Farbe_DropDownClosed" />
<Button Content="Liste öffnen" Click="Oeffnen_Click" />
<TextBlock Text="10 000 Einträge, Liste höchstens 160 hoch" FontWeight="SemiBold" />
<!-- Eine lange Liste: nur die sichtbaren Zeilen werden angelegt, die Höhe der Liste ist begrenzt. -->
<ComboBox Width="180" ItemsSource="{x:Static local:ComboBoxVorfuehrung.Zahlen}" MaxDropDownHeight="160" SelectedIndex="0" />
<TextBlock Text="Deaktiviert" FontWeight="SemiBold" />
<ComboBox Width="180" ItemsSource="{x:Static local:ComboBoxVorfuehrung.Aus}" SelectedIndex="0" IsEnabled="False" />
<TextBlock x:Name="Meldung" Text="Gewählt: Blau." />
<TextBlock Text="Editierbar" FontWeight="SemiBold" />
<!-- Editierbar: Tippen ergänzt den ersten passenden Ort markiert und wählt ihn; ohne Treffer bleibt der Text frei. -->
<ComboBox x:Name="Ort" Width="180" IsEditable="True" PlaceholderText="Ort eingeben" ItemsSource="{x:Static local:ComboBoxVorfuehrung.Orte}"
SelectionChanged="Ort_SelectionChanged" />
<ToggleSwitch OffContent="Änderbar" OnContent="Nur lesen" Checked="NurLesen_Checked" Unchecked="NurLesen_Unchecked" />
<TextBlock x:Name="Stand" Text="Text: „“, gewählt: nichts" />
</StackPanel>ComboBoxSeite.kxaml.cs
using System.Globalization;
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class ComboBoxSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new ComboBoxVorfuehrung();
}
/// <summary>KXAML-Fassung der ComboBox-Seite: der Baum steht in ComboBoxSeite.kxaml, hier die Daten und das Verhalten.</summary>
public sealed partial class ComboBoxVorfuehrung
{
/// <summary>Die Einträge der Listen (im KXAML über x:Static).</summary>
public static readonly string[] Farben = ["Rot", "Orange", "Gelb", "Grün", "Blau", "Violett"];
public static readonly string[] Zahlen = BaueZahlen();
public static readonly string[] Aus = ["Nicht bedienbar"];
public static readonly string[] Orte = ["Basel", "Bern", "Biel", "Chur", "Genf", "Lausanne", "Lugano", "Luzern", "St. Gallen", "Winterthur", "Zürich"];
public ComboBoxVorfuehrung()
{
InitializeComponent();
Ort.Abonniere(ComboBox.TextProperty, (_, _, _) => Stand.Text = ComboBoxSeite.Stand(Ort));
}
private void Ort_SelectionChanged(object sender, SelectionChangedEventArgs e) => Stand.Text = ComboBoxSeite.Stand(Ort);
private void NurLesen_Checked(object sender, RoutedEventArgs e) => Ort.IsReadOnly = true;
private void NurLesen_Unchecked(object sender, RoutedEventArgs e) => Ort.IsReadOnly = false;
private static string[] BaueZahlen()
{
var zahlen = new string[10_000];
for (int i = 0; i < zahlen.Length; i++) zahlen[i] = $"Nummer {(i + 1).ToString("N0", CultureInfo.InvariantCulture)}";
return zahlen;
}
private void ZeigeWahl() => Meldung.Text = Farbe.SelectedItem is { } wahl ? $"Gewählt: {wahl}." : "Nichts gewählt.";
private void Farbe_SelectionChanged(object sender, SelectionChangedEventArgs e) => ZeigeWahl();
private void Farbe_DropDownOpened(object? sender, EventArgs e) => Meldung.Text = "Die Liste ist offen.";
private void Farbe_DropDownClosed(object? sender, EventArgs e) => ZeigeWahl();
private void Oeffnen_Click(object sender, RoutedEventArgs e) => Farbe.IsDropDownOpen = true;
}C#
ComboBoxSeite.cs
using System.Globalization;
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: <see cref="ComboBox"/>.</summary>
public sealed partial class ComboBoxSeite : GalerieSeite
{
public override string Titel => "ComboBox";
public override string Beschreibung =>
"Ein Klappfeld: zeigt die gewählte Möglichkeit, die Liste klappt darunter auf. Der Fokus bleibt im Feld; die Pfeile "
+ "heben in der offenen Liste eine Stelle hervor, Eingabe übernimmt, Escape schliesst. Getippte Buchstaben springen "
+ "zum passenden Eintrag. Editierbar (IsEditable) ist die Box ein Textfeld: Tippen ergänzt den ersten passenden Ort markiert und wählt ihn.";
public override string Stichworte => "Klappfeld Kombinationsfeld Dropdown Auswahl IsDropDownOpen SelectedItem MaxDropDownHeight editierbar IsEditable Ergänzung Text";
internal static string Stand(ComboBox box) => $"Text: „{box.Text}“, gewählt: {box.SelectedItem ?? "nichts"}";
public override string Datei => nameof(ComboBoxSeite);
public override UIElement Baue()
{
var meldung = new TextBlock { Text = "Gewählt: Blau." };
var farbe = new ComboBox { Width = 180, ItemsSource = new[] { "Rot", "Orange", "Gelb", "Grün", "Blau", "Violett" }, SelectedIndex = 4 };
void ZeigeWahl() => meldung.Text = farbe.SelectedItem is { } wahl ? $"Gewählt: {wahl}." : "Nichts gewählt.";
farbe.SelectionChanged += (_, _) => ZeigeWahl();
farbe.DropDownOpened += (_, _) => meldung.Text = "Die Liste ist offen.";
farbe.DropDownClosed += (_, _) => ZeigeWahl();
// Eine lange Liste: nur die sichtbaren Zeilen werden angelegt, die Höhe der Liste ist begrenzt.
var zahlen = new string[10_000];
for (int i = 0; i < zahlen.Length; i++) zahlen[i] = $"Nummer {(i + 1).ToString("N0", CultureInfo.InvariantCulture)}";
var viele = new ComboBox { Width = 180, ItemsSource = zahlen, MaxDropDownHeight = 160, SelectedIndex = 0 };
var aus = new ComboBox { Width = 180, ItemsSource = new[] { "Nicht bedienbar" }, SelectedIndex = 0, IsEnabled = false };
var oeffnen = new Button { Content = "Liste öffnen" };
oeffnen.Click += (_, _) => farbe.IsDropDownOpen = true;
var seite = new StackPanel { Spacing = 12 };
seite.Children.Add(new TextBlock { Text = "Farbe", FontWeight = 600 });
seite.Children.Add(farbe);
seite.Children.Add(oeffnen);
seite.Children.Add(new TextBlock { Text = "10 000 Einträge, Liste höchstens 160 hoch", FontWeight = 600 });
seite.Children.Add(viele);
seite.Children.Add(new TextBlock { Text = "Deaktiviert", FontWeight = 600 });
seite.Children.Add(aus);
seite.Children.Add(meldung);
// Editierbar: Tippen ergänzt den ersten passenden Ort markiert und wählt ihn; ohne Treffer bleibt der Text frei.
var ort = new ComboBox { Width = 180, IsEditable = true, PlaceholderText = "Ort eingeben", ItemsSource = ComboBoxVorfuehrung.Orte };
var stand = new TextBlock { Text = "Text: „“, gewählt: nichts" };
ort.Abonniere(ComboBox.TextProperty, (_, _, _) => stand.Text = Stand(ort));
ort.SelectionChanged += (_, _) => stand.Text = Stand(ort);
var nurLesen = new ToggleSwitch { OffContent = "Änderbar", OnContent = "Nur lesen" };
nurLesen.Checked += (_, _) => ort.IsReadOnly = true;
nurLesen.Unchecked += (_, _) => ort.IsReadOnly = false;
seite.Children.Add(new TextBlock { Text = "Editierbar", FontWeight = 600 });
seite.Children.Add(ort);
seite.Children.Add(nurLesen);
seite.Children.Add(stand);
return seite;
}
}