In Windows Forms bei
Labels nur mühselig abstellbar, kann man mit dieser angefügten Eigenschaft - für WPF - einfach das Kopieren des Inhalts eines
Labels bei einem Doppelklick aktivieren oder deaktivieren.
Das Kopieren funktioniert aber auch bei anderen Controls wie
TextBlock und
Image sowie bei
Run-Elementen.
HinweisIch bin der Meinung mal eine Einstellung im Windows gesehen zu haben mit der man das Kopieren bei einem Doppelklick deaktivieren kann. Wenn jemand diese Einstellung kennt, soll er diese bitte in den Kommentaren posten - ich ergänze meine Klasse entsprechend.
Benötigte NamespacesSystem
System.Windows
System.Windows.Controls
System.Windows.Documents
System.Windows.Input
System.Windows.Media.Imaging
System.Linq
Beispiellocal ist der XML Namespace in dem die
CopyByDoubleClickHelper-Klasse liegt.
<StackPanel>
<Label Content="Label" l:CopyByDoubleClickHelper.CopyToClipboardByDoubleClick="true"/>
<Image Source="D:\Test\testImage.png" l:CopyByDoubleClickHelper.CopyToClipboardByDoubleClick="true" Height="50" HorizontalAlignment="Left"/>
<TextBlock Text="TextBlock" l:CopyByDoubleClickHelper.CopyToClipboardByDoubleClick="true"/>
<TextBlock><Run l:CopyByDoubleClickHelper.CopyToClipboardByDoubleClick="True" Text="Run"/></TextBlock>
</StackPanel>
/// <summary>
/// Kopiert den Inhalt eines Steuerelements in die Zwischenablage wenn doppelt darauf geklickt wird.
/// </summary>
public class CopyByDoubleClickHelper : DependencyObject
{
/// <summary>
/// Ruft den Wert der angefügten Eigenschaft für ein Steuerelement ab.
/// </summary>
/// <param name="obj">Das Steuerelement dessen angefügte Eigenschaft ausgelsen werden soll.</param>
/// <returns><c>true</c>, wenn das Kopieren bei einem Doppelklick aktiviert ist; andernfalls <c>false</c></returns>
public static bool GetCopyToClipboardByDoubleClick(DependencyObject obj)
{
return (bool)obj.GetValue(CopyToClipboardByDoubleClickProperty);
}
/// <summary>
/// Setzt den Wert der angefügten Eigenschaft für ein Steuerelement.
/// </summary>
/// <param name="obj">Ein Steuerelement dessen angefügte Eigenschaft gesetzt weren soll.</param>
/// <param name="value">Der zu setzende Wert der Eigenschaft.</param>
public static void SetCopyToClipboardByDoubleClick(DependencyObject obj, bool value)
{
obj.SetValue(CopyToClipboardByDoubleClickProperty, value);
}
/// <summary>
/// Stellt die angefügte CopyToClipboardByDoubleClick-Abhängigkeitseigenschaft dar.
/// </summary>
public static readonly DependencyProperty CopyToClipboardByDoubleClickProperty = DependencyProperty.RegisterAttached("CopyToClipboardByDoubleClick", typeof(bool), typeof(CopyByDoubleClickHelper), new PropertyMetadata(false, OnCopyToClipboardByDoubleClickChanged));
private static void OnCopyToClipboardByDoubleClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//Je nach Controltyp andere Events abonnieren um verschiedene Typen zu unterstützen
if (d is Control)
if ((bool)e.NewValue == true)
(d as Control).PreviewMouseDoubleClick += control_PreviewMouseDoubleClick;
else
(d as System.Windows.Controls.Control).PreviewMouseDoubleClick -= control_PreviewMouseDoubleClick;
else if (d is UIElement)
if ((bool)e.NewValue == true)
(d as UIElement).PreviewMouseLeftButtonDown += nocontrol_PreviewMouseLeftButtonDown;
else
(d as UIElement).PreviewMouseLeftButtonDown -= nocontrol_PreviewMouseLeftButtonDown;
else if (d is Run)
if ((bool)e.NewValue == true)
(d as Run).PreviewMouseLeftButtonDown += nocontrol_PreviewMouseLeftButtonDown;
else
(d as Run).PreviewMouseLeftButtonDown -= nocontrol_PreviewMouseLeftButtonDown;
else
throw new NotSupportedException("unsupported control");//Kein passendes Control gefunden
}
static void nocontrol_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
control_PreviewMouseDoubleClick(sender, e);
}
static void control_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
//Typ des Contorls heraus finden und Inhalt auslesen
object content = null;
switch (GetKnownBaseType(sender.GetType(), "System.Windows.Controls.Image", "System.Windows.Controls.ContentControl", "System.Windows.Controls.TextBlock", "System.Windows.Documents.Run"))
{
case "System.Windows.Controls.Image":
content = (sender as Image).Source;
break;
case "System.Windows.Controls.ContentControl":
content = (sender as ContentControl).Content;
break;
case "System.Windows.Controls.TextBlock":
content = (sender as TextBlock).Text;
break;
case "System.Windows.Documents.Run":
content = (sender as Run).Text;
break;
}
//Typ des Inhalts bestimmen und in die Zwischenablage setzen
switch (GetKnownBaseType(content.GetType(), "System.String", "System.Windows.Media.Imaging.BitmapSource"))
{
case "System.String":
Clipboard.SetText(content.ToString());
break;
case "System.Windows.Media.Imaging.BitmapSource":
Clipboard.SetImage(content as BitmapSource);
break;
default:
throw new NotSupportedException("Not supported control or unknown content type.");
}
}
/// <summary>
/// Sucht den Basistyp eines Typs, dessen voller Name bekannt ist.
/// </summary>
/// <param name="type">Der abgeleitete Typ.</param>
/// <param name="knownTypes">Eine Liste mit Namen von bekannten Basistypen.</param>
/// <returns><c>null</c> wenn kein Typ gefunden wurde; andernfalls der Name des Typs.</returns>
static string GetKnownBaseType(Type type, params string[] knownTypes)
{
do
{
if (knownTypes.Contains(type.FullName))
return type.FullName;
type = type.BaseType;
} while (type.FullName != "System.Object");
return null;
}
}
Kommentare zum Snippet