C# TextBlock Inhalt beim Klick kopieren

toma123

Banned
Registriert
Apr. 2020
Beiträge
100
Ich habe verschiedene TextBlock's und würde diesen gern ein Command zuweisen, damit beim darauf klicken der Text in die Zwischenablage kopiert wird. In WinForms würde ich dies über Eventhandler machen, die es ja so in WPF nicht mehr gibt bzw. durch Command abgelöst wurden.

Dass ich das ganze via Binding machen muss ist mir klar, allerdings habe ich noch keine gute Anleitung, wie ich im günstigen Fall vorgehe, gefunden bzw. gelesen. Habt ihr das etwas wo mit weiterhelfen kann?
 
Dafür kannst du dir erst mal den Behaviors Namespace in XAML hinzufügen:
XML:
xmlns:beh="http://schemas.microsoft.com/xaml/behaviors"

Damit kannst du dann nämlich normale Events über die Interaction Trigger ansteuern, zb so:
Code:
<TextBlock Text="Text" x:Name="TextBlockToCopy">
    <beh:Interaction.Triggers>
        <beh:EventTrigger EventName="MouseLeftButtonUp">
            <beh:InvokeCommandAction Command="{Binding CopyTextCommand}"
                         CommandParameter="{Binding Text, ElementName=TextBlockToCopy}" />
        </beh:EventTrigger>
    </beh:Interaction.Triggers>
</TextBlock>

Ich gehe mal davon aus, dass der Text des TextBlock nicht schon gebindet ist, sonst hätte man das Problem ja nicht :p
Getestet ist es nicht, aber in die Richtung sollte es gehen.
Wenns nicht geht, kann ich es nochmal bei mir testen :)
 
Zuletzt bearbeitet:
Wenn es nur darum geht, dass der Text in die Zwischenablage kopiert wird, kann man auch von MVVM abweichen und das einfach im Code-Behind über die klassischen Events machen. Meiner Meinung gehört ein Kopiervorgang in die Zwischenablage nicht in das ViewModel, weil es einfach nur eine Sache der Oberfläche ist.

Das Non-Plus-Ultra wäre eine Attached Property zu schreiben, welches du dann einfach an deinen TextBlock anfügst. Das ist quasi das Gleiche wie oben, nur mit dem Unterschied, dass der Code dann wiederverwendbar wäre.

So in etwa:

Attached Property:
C#:
public static class CopyClipboardExtension
{
    // Using a DependencyProperty as the backing store for EnableCopyToClipboard. This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EnableCopyToClipboardProperty = DependencyProperty.RegisterAttached("EnableCopyToClipboard", typeof(bool), typeof(CopyClipboardExtension), new PropertyMetadata(false, EnableCopyToClipboard));

    public static bool GetEnableCopyToClipboard(DependencyObject obj)
    {
        return (bool)obj.GetValue(EnableCopyToClipboardProperty);
    }

    public static void SetEnableCopyToClipboard(DependencyObject obj, bool value)
    {
        obj.SetValue(EnableCopyToClipboardProperty, value);
    }

    private static void CopyToClipboard(object sender, MouseButtonEventArgs e)
    {
        if (sender is TextBlock textBlock)
        {
            Clipboard.SetDataObject(textBlock.Text);
        }
    }

    private static void EnableCopyToClipboard(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // only allow attached property on TextBlock
        if (d is TextBlock textBlock)
        {
            // always remove the old event handler for memory reasons
            textBlock.MouseLeftButtonUp -= CopyToClipboard;

            // if we want to enable copy to clipboard
            if ((bool)e.NewValue)
            {
                textBlock.MouseLeftButtonUp += CopyToClipboard;
            }
        }
    }
}

In deiner XAML dann oben den Namespace deiner der Attached Property einfügen (falls anders als local)
XML:
xmlns:ap="clr-namespace:|NameSpace|>;assembly=|NameDerBibliothek|
und dann nur noch die Attached Property an den TextBlock anfügen
XML:
<TextBlock ap:CopyClipboardExtension.EnableCopyToClipboard="true"></TextBlock>

Diese Attached Property kann man nun immer wieder verwenden. Habe Sie nicht getestet, müsste aber im Groben richtig sein.

Der Weg von @davisx2 funktioniert natürlich auch. Meiner Meinung nach, hat das aber nichts im ViewModel zu suchen.
 
  • Gefällt mir
Reaktionen: davisx2
marcOcram schrieb:
Wenn es nur darum geht, dass der Text in die Zwischenablage kopiert wird, kann man auch von MVVM abweichen und das einfach im Code-Behind über die klassischen Events machen. Meiner Meinung gehört ein Kopiervorgang in die Zwischenablage nicht in das ViewModel, weil es einfach nur eine Sache der Oberfläche ist.

Allerdings müsste ich dann ja jedem TextBlock ein Tastenklick und Mausklick Event hinzufügen.
 
Genau deswegen dann das Attached Property. Das klatscht du an jeden TextBlock der das Verhalten braucht und fertig. Hängt halt immer vom Anwendungsfall ab. Brauchst du es nur ein einziges Mal, dann über Events. Brauchst du es öfter, dann ein Attached Property. Ist damit eine größere Logik verbunden gehst du über das ViewModel und dann entsprechend weiter.
 
  • Gefällt mir
Reaktionen: mylight
Was Attached Property machen ist mir mittlerweile klar, allerdings weis ich nicht so recht wie ich das ganze einsetze. Hast du vlt. ein Tutorial wie ich da im günstigsten Fall vorgehen kann?
 
Ein Beispiel meiner Meinung nach ist die PasswordBox von WPF. Oft ist es so, dass du das Passwort natürlich auch im ViewModel möchtest. Leider kriegt man von der PasswordBox das Passwort aber nicht über ein Binding. Weder als SecureString noch als ganz normalen string.
Die PasswordBox hat sogar eine Property Password, jedoch kann man an diese nicht binden. Um das zu umgehen, kann man eine AttachedProperty schreiben. Diese kopiert das Passwort bei Änderung dann in die entsprechende Property.
Das wird zum Beispiel hier gemacht: https://wpftutorial.net/PasswordBox.html
 
Danke für den Link, allerdings wird da nicht sonderlich viel erklärt. Gibt es vielleicht noch andere Tutorials wo es es genauer erklärt wird?
 
Viel mehr gibt es dazu eigentlich nicht zu wissen. Im Groben wird eine DependencyProperty mit eigens programmiertem Verhalten an ein DependencyObject angehängt. Dementsprechend würde ich dazu die Dokumentation von Microsoft empfehlen oder einfach nach Tutorials suchen, die diese Stichworte beinhalten. Grid.Row="1" und Grid.Column="2" sind z. B. auch Attached Properties an deren das übergeordnete Grid erkennen kann, wo die Elemente hin sollen.
 
Zurück
Oben