2010-10-14 26 views
10

Estoy tratando de copiar un cuadro de lista WPF estándar seleccionado Elemento (visualizado) texto al portapapeles en CTRL + C. ¿Hay alguna manera simple de lograr esto? Si es algo que funciona para todas las listboxes en la aplicación ... eso sería genial.WPF listbox copy to clipboard

Gracias de antemano.

+1

Encontré la respuesta en http://blogs.gerodev.com/post/Copy-Selected-Items-in-WPF-Listbox-to-Clipboard.aspx. Pero aún estoy buscando una opción para agregarlo globalmente a la aplicación. – Bhuvan

+0

El enlace de arriba en el comentario está muerto. –

+0

@BenWalker ... bueno, eso era un enlace antiguo. La misma solución se proporciona a continuación por eagleboost – Bhuvan

Respuesta

18

Como estás en WPF lo que podría intentar los comportamientos adjuntos
Lo primero que necesita una clase como esta:

public static class ListBoxBehaviour 
{ 
    public static readonly DependencyProperty AutoCopyProperty = DependencyProperty.RegisterAttached("AutoCopy", 
     typeof(bool), typeof(ListBoxBehaviour), new UIPropertyMetadata(AutoCopyChanged)); 

    public static bool GetAutoCopy(DependencyObject obj_) 
    { 
     return (bool) obj_.GetValue(AutoCopyProperty); 
    } 

    public static void SetAutoCopy(DependencyObject obj_, bool value_) 
    { 
     obj_.SetValue(AutoCopyProperty, value_); 
    } 

    private static void AutoCopyChanged(DependencyObject obj_, DependencyPropertyChangedEventArgs e_) 
    { 
     var listBox = obj_ as ListBox; 
     if (listBox != null) 
     { 
      if ((bool)e_.NewValue) 
      { 
       ExecutedRoutedEventHandler handler = 
        (sender_, arg_) => 
        { 
         if (listBox.SelectedItem != null) 
         { 
          //Copy what ever your want here 
          Clipboard.SetDataObject(listBox.SelectedItem.ToString()); 
         } 
        }; 

       var command = new RoutedCommand("Copy", typeof (ListBox)); 
       command.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Control, "Copy")); 
       listBox.CommandBindings.Add(new CommandBinding(command, handler)); 
      } 
     } 
    } 
} 


Entonces usted tiene el XAML como esto

<ListBox sample:ListBoxBehaviour.AutoCopy="True"> 
    <ListBox.Items> 
    <ListBoxItem Content="a"/> 
    <ListBoxItem Content="b"/> 
    </ListBox.Items> 
</ListBox> 


Actualizaciones: Para el caso más simple, puede acceder al texto de la siguiente manera:

private static string GetListBoxItemText(ListBox listBox_, object item_) 
{ 
    var listBoxItem = listBox_.ItemContainerGenerator.ContainerFromItem(item_) 
        as ListBoxItem; 
    if (listBoxItem != null) 
    { 
    var textBlock = FindChild<TextBlock>(listBoxItem); 
    if (textBlock != null) 
    { 
     return textBlock.Text; 
    } 
    } 
    return null; 
} 

GetListBoxItemText(myListbox, myListbox.SelectedItem) 
FindChild<T> is a function to find a child of type T of a DependencyObject 

Pero al igual que el ListBoxItem podría estar obligado a oponerse, ItemTemplate podría ser diferente, así que no se puede confiar en él en proyectos reales.

+0

Gracias por esta solución elegante y casi perfecta. Supongo que la única parte que falta es esa, cómo detectar el presentador de contenido y obtener el texto real que se muestra, en el caso de la arquitectura MVVM, ya que no vincularemos cadenas simples, sino más bien objetos. – Bhuvan