Zum Inhalt
Kuonen.UI

SelectableTextBlock

Wählbarer Text: ziehen, Doppelklick wählt ein Wort, Dreifachklick alles, Umschalt+Klick und Umschalt+Pfeile erweitern; Strg+A, Strg+C, Esc leert. Rechtsklick oder langes Drücken öffnet „Kopieren“ und „Alles auswählen“. Links im Text bleiben klickbar.

Vorführung: SelectableTextBlockVorführung: SelectableTextBlock

KXAML

SelectableTextBlockSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.SelectableTextBlockVorfuehrung"
            Spacing="8">
  <TextBlock Text="Absatz mit Formaten und Link" FontWeight="SemiBold" />
  <SelectableTextBlock x:Name="Absatz" TextWrapping="Wrap" Width="360" HorizontalAlignment="Left" SelectionChanged="Absatz_SelectionChanged">
    <Run Text="Dieser Absatz lässt sich wählen und kopieren. Er hat " />
    <Bold><Run Text="fette Wörter" /></Bold>
    <Run Text=", einen " />
    <Hyperlink x:Name="Verweis"><Run Text="Link" /></Hyperlink>
    <Run Text=", der beim Klicken auslöst, und bricht am Rand um." />
  </SelectableTextBlock>
  <TextBlock x:Name="Meldung" Text="Gewählt: –" />
  <TextBlock x:Name="LinkMeldung" Text="Link: nicht ausgelöst" />
  <StackPanel Orientation="Horizontal" Spacing="8">
    <Button Content="Alles auswählen" Click="Alles_Click" />
    <Button Content="Kopieren" Click="Kopieren_Click" />
  </StackPanel>
  <TextBlock Text="Einzeilig" FontWeight="SemiBold" />
  <SelectableTextBlock Text="Bestellnummer 2026-10-0815" />
</StackPanel>
SelectableTextBlockSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;

namespace Kuonen.UI.Galerie.Seiten;

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

/// <summary>KXAML-Fassung der SelectableTextBlock-Seite: der Baum steht in SelectableTextBlockSeite.kxaml, hier nur das Verhalten.</summary>
public sealed partial class SelectableTextBlockVorfuehrung
{
    public SelectableTextBlockVorfuehrung()
    {
        InitializeComponent();
        Verweis.Click += (_, _) => LinkMeldung.Text = "Link: ausgelöst";
    }

    private void Absatz_SelectionChanged(object? sender, EventArgs e) => Meldung.Text = SelectableTextBlockSeite.Gewaehlt(Absatz);

    private void Alles_Click(object sender, RoutedEventArgs e) => Absatz.SelectAll();

    private void Kopieren_Click(object sender, RoutedEventArgs e) => Absatz.Copy();
}

C#

SelectableTextBlockSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: <see cref="SelectableTextBlock"/>.</summary>
public sealed partial class SelectableTextBlockSeite : GalerieSeite
{
    public override string Titel => "SelectableTextBlock";

    public override string Beschreibung =>
        "Wählbarer Text: ziehen, Doppelklick wählt ein Wort, Dreifachklick alles, Umschalt+Klick und Umschalt+Pfeile erweitern; Strg+A, Strg+C, Esc leert. "
        + "Rechtsklick oder langes Drücken öffnet „Kopieren“ und „Alles auswählen“. Links im Text bleiben klickbar.";

    public override string Stichworte => "Text wählen markieren kopieren Auswahl Zwischenablage SelectableTextBlock SelectedText CopyingToClipboard Link";

    public override string Datei => nameof(SelectableTextBlockSeite);

    internal const string Leer = "Gewählt: –";

    internal static string Gewaehlt(SelectableTextBlock block) => block.SelectedText.Length == 0 ? Leer : "Gewählt: " + block.SelectedText;

    public override UIElement Baue()
    {
        var absatz = new SelectableTextBlock { TextWrapping = TextWrapping.Wrap, Width = 360, HorizontalAlignment = HorizontalAlignment.Left };
        absatz.Inlines.Add(new Run("Dieser Absatz lässt sich wählen und kopieren. Er hat "));
        var fett = new Bold();
        fett.Inlines.Add(new Run("fette Wörter"));
        absatz.Inlines.Add(fett);
        absatz.Inlines.Add(new Run(", einen "));
        var verweis = new Hyperlink(new Run("Link"));
        absatz.Inlines.Add(verweis);
        absatz.Inlines.Add(new Run(", der beim Klicken auslöst, und bricht am Rand um."));
        var meldung = new TextBlock { Text = Leer };
        var link = new TextBlock { Text = "Link: nicht ausgelöst" };
        absatz.SelectionChanged += (_, _) => meldung.Text = Gewaehlt(absatz);
        verweis.Click += (_, _) => link.Text = "Link: ausgelöst";
        var alles = new Button { Content = "Alles auswählen" };
        alles.Click += (_, _) => absatz.SelectAll();
        var kopieren = new Button { Content = "Kopieren" };
        kopieren.Click += (_, _) => absatz.Copy();
        return new StackPanel
        {
            Spacing = 8,
            Children =
            {
                new TextBlock { Text = "Absatz mit Formaten und Link", FontWeight = 600 },
                absatz,
                meldung,
                link,
                new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8, Children = { alles, kopieren } },
                new TextBlock { Text = "Einzeilig", FontWeight = 600 },
                new SelectableTextBlock { Text = "Bestellnummer 2026-10-0815" },
            },
        };
    }
}