Zum Inhalt
Kuonen.UI

MessageBox

Eine Meldung mit Knöpfen, nur asynchron: ZeigeAsync öffnet ein modales Fenster und liefert den gedrückten Knopf. Enter löst den Standardknopf aus, Esc den Abbruchknopf (bei Ja/Nein ohne Abbrechen wirkt Esc nicht, wie unter Windows), Strg+C kopiert den Text. Die Folge der Knöpfe richtet sich nach der Designsprache; die Texte der Knöpfe stehen in Deutsch, Englisch, Französisch und Italienisch.

Vorführung: MessageBoxVorführung: MessageBox

KXAML

MessageBoxSeite.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.MessageBoxVorfuehrung"
            Spacing="12">
  <TextBlock Text="Knöpfe" FontWeight="SemiBold" />
  <ComboBox x:Name="Satz" Width="220" ItemsSource="{x:Static local:MessageBoxSeite.Knoepfe}" SelectedIndex="3" />
  <TextBlock Text="Symbol" FontWeight="SemiBold" />
  <ComboBox x:Name="Symbol" Width="220" ItemsSource="{x:Static local:MessageBoxSeite.Symbole}" SelectedIndex="4" />
  <TextBlock Text="Standardknopf" FontWeight="SemiBold" />
  <ComboBox x:Name="Standard" Width="220" ItemsSource="{x:Static local:MessageBoxSeite.Standardknoepfe}" SelectedIndex="0" />
  <TextBlock Text="Sprache der Standardtexte (nur für diese Meldung)" FontWeight="SemiBold" />
  <ComboBox x:Name="Sprache" Width="220" ItemsSource="{x:Static local:MessageBoxSeite.Sprachen}" SelectedIndex="0" />
  <TextBlock Text="Titel" FontWeight="SemiBold" />
  <TextBox x:Name="Titel" Width="320" HorizontalAlignment="Left" Text="Löschen" />
  <TextBlock Text="Text" FontWeight="SemiBold" />
  <TextBox x:Name="Text" Width="320" HorizontalAlignment="Left" Text="Soll die Datei wirklich gelöscht werden?" />
  <Button x:Name="Zeigen" Content="Zeigen" Style="{x:Static Fluent.AkzentButton}" Click="Zeigen_Click" />
  <TextBlock x:Name="Ergebnis" Text="Noch keine Meldung gezeigt." TextWrapping="Wrap" />
</StackPanel>
MessageBoxSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;

namespace Kuonen.UI.Galerie.Seiten;

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

/// <summary>KXAML-Fassung der MessageBox-Seite: der Baum steht in MessageBoxSeite.kxaml, hier nur das Verhalten (ZeigeAsync im Code-Behind).</summary>
public sealed partial class MessageBoxVorfuehrung
{
    public MessageBoxVorfuehrung() => InitializeComponent();

    private async void Zeigen_Click(object sender, RoutedEventArgs e)
    {
        if (MessageBoxSeite.FensterVon(Zeigen) is not { } besitzer || Satz.SelectedIndex < 0) return;
        Ergebnis.Text = "Die Meldung ist offen; das Fenster ist gesperrt.";
        var wahl = await MessageBoxSeite.ZeigeInSprache(besitzer, Sprache.SelectedIndex, Text.Text, Titel.Text, (MessageBoxButton)Satz.SelectedIndex,
            MessageBoxSeite.Symbol(Symbol.SelectedIndex), MessageBoxSeite.Standard(Standard.SelectedIndex));
        Ergebnis.Text = "Ergebnis: " + MessageBoxSeite.Name(wahl);
    }
}

C#

MessageBoxSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
using Kuonen.UI.Themes;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: <see cref="MessageBox"/>, Standardknöpfe und Standardtexte.</summary>
public sealed partial class MessageBoxSeite : GalerieSeite
{
    /// <summary>Die Knopfsätze in der Reihenfolge von <see cref="MessageBoxButton"/> (der Index ist der Wert).</summary>
    public static readonly string[] Knoepfe = ["OK", "OKCancel", "AbortRetryIgnore", "YesNoCancel", "YesNo", "RetryCancel", "CancelTryContinue"];

    public static readonly string[] Symbole = ["None", "Information", "Warning", "Error", "Question"];

    public static readonly string[] Standardknoepfe = ["Keiner (der erste)", "OK", "Cancel", "Yes", "No", "Retry", "Abort", "Ignore", "TryAgain", "Continue"];

    public static readonly string[] Sprachen = ["de", "en", "fr", "it"];

    public override string Titel => "MessageBox";

    public override string Beschreibung =>
        "Eine Meldung mit Knöpfen, nur asynchron: ZeigeAsync öffnet ein modales Fenster und liefert den gedrückten Knopf. Enter löst den "
        + "Standardknopf aus, Esc den Abbruchknopf (bei Ja/Nein ohne Abbrechen wirkt Esc nicht, wie unter Windows), Strg+C kopiert den Text. "
        + "Die Folge der Knöpfe richtet sich nach der Designsprache; die Texte der Knöpfe stehen in Deutsch, Englisch, Französisch und Italienisch.";

    public override string Stichworte => "MessageBox Meldung Dialog Nachricht Knöpfe IsDefault IsCancel Standardknopf Standardtexte Sprache ZeigeAsync MessageBoxButton MessageBoxImage MessageBoxResult";

    public override string Datei => nameof(MessageBoxSeite);

    /// <summary>Die Werte zu den Einträgen von <see cref="Symbole"/>.</summary>
    internal static MessageBoxImage Symbol(int index) => index switch
    {
        1 => MessageBoxImage.Information,
        2 => MessageBoxImage.Warning,
        3 => MessageBoxImage.Error,
        4 => MessageBoxImage.Question,
        _ => MessageBoxImage.None,
    };

    /// <summary>Die Werte zu den Einträgen von <see cref="Standardknoepfe"/>.</summary>
    internal static MessageBoxResult Standard(int index) => index switch
    {
        1 => MessageBoxResult.OK,
        2 => MessageBoxResult.Cancel,
        3 => MessageBoxResult.Yes,
        4 => MessageBoxResult.No,
        5 => MessageBoxResult.Retry,
        6 => MessageBoxResult.Abort,
        7 => MessageBoxResult.Ignore,
        8 => MessageBoxResult.TryAgain,
        9 => MessageBoxResult.Continue,
        _ => MessageBoxResult.None,
    };

    internal static string Name(MessageBoxResult ergebnis) => ergebnis switch
    {
        MessageBoxResult.OK => "OK",
        MessageBoxResult.Cancel => "Cancel",
        MessageBoxResult.Abort => "Abort",
        MessageBoxResult.Retry => "Retry",
        MessageBoxResult.Ignore => "Ignore",
        MessageBoxResult.Yes => "Yes",
        MessageBoxResult.No => "No",
        MessageBoxResult.TryAgain => "TryAgain",
        MessageBoxResult.Continue => "Continue",
        _ => "None",
    };

    // Die Meldung baut ihre Texte beim Aufruf: die Sprache gilt nur dafür und wird gleich zurückgesetzt (die App behält ihre).
    internal static Task<MessageBoxResult> ZeigeInSprache(Window besitzer, int sprache, string text, string titel, MessageBoxButton satz, MessageBoxImage symbol, MessageBoxResult standard)
    {
        string alt = Standardtexte.Sprache;
        if (sprache >= 0) Standardtexte.Sprache = Sprachen[sprache];
        try { return MessageBox.ZeigeAsync(besitzer, text, titel, satz, symbol, standard); }
        finally { Standardtexte.Sprache = alt; }
    }

    // Das Fenster, in dem diese Seite steht: Besitzer der Meldung.
    internal static Window? FensterVon(Visual element)
    {
        for (Visual? v = element; v is not null; v = v.VisualParent)
            if (v is Window fenster) return fenster;
        return null;
    }

    public override UIElement Baue()
    {
        var satz = new ComboBox { Width = 220, ItemsSource = Knoepfe, SelectedIndex = 3 };
        var symbol = new ComboBox { Width = 220, ItemsSource = Symbole, SelectedIndex = 4 };
        var standard = new ComboBox { Width = 220, ItemsSource = Standardknoepfe, SelectedIndex = 0 };
        var sprache = new ComboBox { Width = 220, ItemsSource = Sprachen, SelectedIndex = 0 };
        var titel = new TextBox { Width = 320, HorizontalAlignment = HorizontalAlignment.Left, Text = "Löschen" };
        var text = new TextBox { Width = 320, HorizontalAlignment = HorizontalAlignment.Left, Text = "Soll die Datei wirklich gelöscht werden?" };
        var ergebnis = new TextBlock { Text = "Noch keine Meldung gezeigt.", TextWrapping = TextWrapping.Wrap };

        var zeigen = new Button { Content = "Zeigen", Style = Fluent.AkzentButton };
        zeigen.Click += async (_, _) =>
        {
            if (FensterVon(zeigen) is not { } besitzer || satz.SelectedIndex < 0) return;
            ergebnis.Text = "Die Meldung ist offen; das Fenster ist gesperrt.";
            var wahl = await ZeigeInSprache(besitzer, sprache.SelectedIndex, text.Text, titel.Text, (MessageBoxButton)satz.SelectedIndex, Symbol(symbol.SelectedIndex), Standard(standard.SelectedIndex));
            ergebnis.Text = "Ergebnis: " + Name(wahl);
        };

        var seite = new StackPanel { Spacing = 12 };
        seite.Children.Add(new TextBlock { Text = "Knöpfe", FontWeight = 600 });
        seite.Children.Add(satz);
        seite.Children.Add(new TextBlock { Text = "Symbol", FontWeight = 600 });
        seite.Children.Add(symbol);
        seite.Children.Add(new TextBlock { Text = "Standardknopf", FontWeight = 600 });
        seite.Children.Add(standard);
        seite.Children.Add(new TextBlock { Text = "Sprache der Standardtexte (nur für diese Meldung)", FontWeight = 600 });
        seite.Children.Add(sprache);
        seite.Children.Add(new TextBlock { Text = "Titel", FontWeight = 600 });
        seite.Children.Add(titel);
        seite.Children.Add(new TextBlock { Text = "Text", FontWeight = 600 });
        seite.Children.Add(text);
        seite.Children.Add(zeigen);
        seite.Children.Add(ergebnis);
        return seite;
    }
}