Zum Inhalt
Kuonen.UI

Taskleiste

Ein TrayIcon zeigt ein Symbol im Infobereich der Taskleiste (Windows), als StatusNotifierItem (Linux; GNOME mit AppIndicator-Erweiterung) oder in der Menüleiste (macOS). Es hat ein Bild, einen Tooltip, ein Menü (ein gewöhnliches ContextMenu, gezeigt als Menü der Plattform) und meldet den Klick. Erst IsVisible zeigt es, Dispose nimmt es weg. Das Symbol dieser Seite bleibt, bis das Kästchen es wieder ausschaltet.

Vorführung: TaskleisteVorführung: Taskleiste

KXAML

TaskleisteSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.TaskleisteVorfuehrung"
            Spacing="12">
  <TextBlock Text="Symbol" FontWeight="SemiBold" />
  <CheckBox x:Name="Zeigen" Content="Symbol zeigen" />
  <TextBlock Text="Tooltip" FontWeight="SemiBold" />
  <TextBox x:Name="Tooltip" Width="320" HorizontalAlignment="Left" Text="Kuonen.UI-Galerie" />
  <TextBlock x:Name="Ergebnis" Text="Noch kein Klick." TextWrapping="Wrap" />
</StackPanel>
TaskleisteSeite.kxaml.cs
using Kuonen.UI;

namespace Kuonen.UI.Galerie.Seiten;

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

/// <summary>KXAML-Fassung der Taskleisten-Seite: der Baum steht in TaskleisteSeite.kxaml; das Symbol (kein Element) baut der Code-Behind.</summary>
public sealed partial class TaskleisteVorfuehrung
{
    public TaskleisteVorfuehrung()
    {
        InitializeComponent();
        _ = new Taskleistensteuerung(Zeigen, Tooltip, Ergebnis);
    }
}

C#

TaskleisteSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Dienste;
using Kuonen.UI.Layout;
using Kuonen.UI.Media;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: ein Symbol im Infobereich der Taskleiste mit Tooltip, Klick und Menü (Plan 6h).</summary>
public sealed partial class TaskleisteSeite : GalerieSeite
{
    public override string Titel => "Taskleiste";

    public override string Beschreibung =>
        "Ein TrayIcon zeigt ein Symbol im Infobereich der Taskleiste (Windows), als StatusNotifierItem (Linux; GNOME mit AppIndicator-Erweiterung) "
        + "oder in der Menüleiste (macOS). Es hat ein Bild, einen Tooltip, ein Menü (ein gewöhnliches ContextMenu, gezeigt als Menü der Plattform) "
        + "und meldet den Klick. Erst IsVisible zeigt es, Dispose nimmt es weg. Das Symbol dieser Seite bleibt, bis das Kästchen es wieder ausschaltet.";

    public override string Stichworte => "TrayIcon Taskleiste Infobereich NotifyIcon StatusNotifierItem NSStatusItem Symbol Tooltip Menü ContextMenu Clicked";

    public override string Datei => nameof(TaskleisteSeite);

    /// <summary>Ein rundes Symbol (32 × 32, vormultipliziert) in Kuonen-Blau mit weissem Punkt.</summary>
    internal static BitmapSource Symbolbild()
    {
        const int n = 32;
        var pixel = new uint[n * n];
        for (int y = 0; y < n; y++)
            for (int x = 0; x < n; x++)
            {
                double dx = x + 0.5 - n / 2.0, dy = y + 0.5 - n / 2.0, r = Math.Sqrt(dx * dx + dy * dy);
                if (r <= 6) pixel[y * n + x] = 0xFFFFFFFFu;
                else if (r <= 15) pixel[y * n + x] = 0xFF0078D4u;
            }
        return BitmapSource.Create(n, n, pixel);
    }

    public override UIElement Baue()
    {
        var zeigen = new CheckBox { Content = "Symbol zeigen" };
        var tooltip = new TextBox { Width = 320, HorizontalAlignment = HorizontalAlignment.Left, Text = "Kuonen.UI-Galerie" };
        var ergebnis = new TextBlock { Text = "Noch kein Klick.", TextWrapping = TextWrapping.Wrap };
        _ = new Taskleistensteuerung(zeigen, tooltip, ergebnis);
        var seite = new StackPanel { Spacing = 12 };
        seite.Children.Add(new TextBlock { Text = "Symbol", FontWeight = 600 });
        seite.Children.Add(zeigen);
        seite.Children.Add(new TextBlock { Text = "Tooltip", FontWeight = 600 });
        seite.Children.Add(tooltip);
        seite.Children.Add(ergebnis);
        return seite;
    }
}

/// <summary>Das Verhalten der Taskleisten-Seite (für beide Fassungen): das Kästchen zeigt das Symbol, der Text wird sein Tooltip, Klick und Menü melden sich.</summary>
internal sealed class Taskleistensteuerung
{
    private readonly TextBlock _ergebnis;
    private int _klicks;

    public Taskleistensteuerung(CheckBox zeigen, TextBox tooltip, TextBlock ergebnis)
    {
        _ergebnis = ergebnis;
        var oeffnen = new MenuItem { Header = "_Galerie zeigen" };
        oeffnen.Click += (_, _) => _ergebnis.Text = "Menü: Galerie zeigen.";
        var aus = new MenuItem { Header = "Symbol _ausblenden" };
        aus.Click += (_, _) => zeigen.IsChecked = false;
        Symbol = new TrayIcon
        {
            Icon = TaskleisteSeite.Symbolbild(), ToolTipText = tooltip.Text, Menu = new ContextMenu { Items = { oeffnen, new Separator(), aus } },
        };
        Symbol.Clicked += (_, _) => _ergebnis.Text = $"Geklickt: {++_klicks}×";
        zeigen.Checked += (_, _) => Zeige(true);
        zeigen.Unchecked += (_, _) => Zeige(false);
        tooltip.TextChanged += (_, _) => Symbol.ToolTipText = tooltip.Text;
    }

    public TrayIcon Symbol { get; }

    private void Zeige(bool an)
    {
        Symbol.IsVisible = an;
        if (an && TrayIcon.Dienst is not { KannSymbole: true }) _ergebnis.Text = "Dieser Host zeigt keine Symbole in der Taskleiste.";
    }
}