2011-02-01 17 views
7

Estoy desarrollando una aplicación similar a Dropbox y muestro los archivos remotos en una vista de lista de WPF. Quiero arrastrar esos elementos y soltarlos en el explorador de Windows. que he visto código como este:WPF: Arrastrar y soltar archivos virtuales en el Explorador de Windows

var dataObject = new DataObject(DataFormats.FileDrop, files.ToArray()); 
dataObject.SetData(DataFormats.StringFormat, dataObject); 
DoDragDrop(dataObject, DragDropEffects.Copy); 

Pero como usted puede pensar, los archivos no están en el sistema local, sin embargo, antes de copiying les tengo que conectar con el servidor, descargar e descomprimir los archivos. Como lo hace un cliente ftp.

No sé cómo hacerlo, pero me preguntaba si hay algún evento "drop" o similar que pueda manejar.

Gracias!

Respuesta

4

Este fragmento:

var virtualFileDataObject = new VirtualFileDataObject(
       // BeginInvoke ensures UI operations happen on the right thread 
       (vfdo) => Dispatcher.BeginInvoke((Action)(() => BusyScreen.Visibility = Visibility.Visible)), 
       (vfdo) => Dispatcher.BeginInvoke((Action)(() => BusyScreen.Visibility = Visibility.Collapsed))); 

      // Provide a virtual file (downloaded on demand), its URL, and descriptive text 
      virtualFileDataObject.SetData(new VirtualFileDataObject.FileDescriptor[] 
      { 
       new VirtualFileDataObject.FileDescriptor 
       { 
        Name = "DelaysBlog.xml", 
        StreamContents = stream => 
         { 
          using(var webClient = new WebClient()) 
          { 
           var data = webClient.DownloadData("http://blogs.msdn.com/delay/rss.xml"); 
           stream.Write(data, 0, data.Length); 
          } 
         } 
       }, 
      }); 
      virtualFileDataObject.SetData(
       (short)(DataFormats.GetDataFormat(CFSTR_INETURLA).Id), 
       Encoding.Default.GetBytes("http://blogs.msdn.com/delay/rss.xml\0")); 
      virtualFileDataObject.SetData(
       (short)(DataFormats.GetDataFormat(DataFormats.Text).Id), 
       Encoding.Default.GetBytes("[The RSS feed for Delay's Blog]\0")); 

      DoDragDropOrClipboardSetDataObject(e.ChangedButton, TextUrl, virtualFileDataObject, DragDropEffects.Copy); 

Utilización de la clase linked debería funcionar. . Muy buena y fácil solución.

+0

Proporcione una descripción general de lo que dice el enlace. [Se desaconsejan las respuestas de solo enlace] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) ya que los enlaces pueden quedar sin efecto. Este ya tiene, en cierta medida, dado que los contenidos originales se movieron. En la URL anterior, todavía hay un puntero a la nueva URL, pero quién sabe durante cuánto tiempo permanecerá allí y durante cuánto tiempo estará disponible la información en la nueva URL ... –

+0

Proporcionando un enlace a una respuesta no es una respuesta, ni es la calidad requerida de una respuesta descrita en las políticas de uso de StackOverflow. Por favor, brinde una respuesta adecuada y voy a votar mejor. Gracias - AMR –

1

http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398!190.entry http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398!199.entry http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398!225.entry

Ver esta serie de artículos. Esto debería ayudarte a comenzar.

EDIT: Ver esto para un amplementation del dragsourceadvisor

internal class ImagesViewPanelDragSourceAdvisor : IDragSourceAdvisor 
{ 
    private FrameworkElement _dragSource; 

    public DependencyObject DragSource 
    { 
     get 
     { 
      return _dragSource; 
     } 
     set 
     { 
      _dragSource = value as FrameworkElement; 
     } 
    } 

    public DependencyObject DragObject { get; set; } 

    public DragDropEffects GetDragDropEffects() 
    { 
     DragDropEffects effects = DragDropEffects.None; 

     FrameworkElement frameworkObj = DragObject as FrameworkElement; 

     if (frameworkObj != null && frameworkObj.DataContext is ImageViewModel) 
     { 
      effects = DragDropEffects.Copy; 
     } 

     return effects; 
    } 

    public IDataObject GetDragDataObject() 
    { 
     Debug.Assert(GetDragDropEffects() != DragDropEffects.None); 

     ImagesViewModel imagesVM = (FrameworkElement)DragSource).DataContext as ImagesViewModel; 

     StringCollection fileList = new StringCollection(); 

     foreach (ImageViewModel imageVM in imagesVM.Items.Where(imageVM => imageVM.IsSelected)) 
     { 
      fileList.Add(imageVM.ImagePath); 
     } 

     Debug.Assert(fileList.Count > 0); 

     DataObject dataObj = new DataObject(); 

     dataObj.SetFileDropList(fileList); 

     return dataObj; 
    } 

    public void FinishDrag(DragDropEffects finalEffect) 
    { 
    } 
+0

Este ejemplo funciona bien entre elementos UIE pero no fuera de ellos (escritorio de Windows por ejemplo). De todos modos, gracias por ayudarme. – Morvader

+0

Funcionará bien con arrastrar y soltar entre el escritorio y su aplicación. Solo necesita una clase adecuada DropTargetAdvisor. Permítanme editar mi respuesta con un ejemplo – NVM

+0

Lo siento, pero es demasiado tiempo para explicar todo aquí. Lo único que debe cambiar es la implementación de DropTargetAdvisor y DragSourceAdvisor de manera adecuada. Lo que puede hacer es hacer lo que hacen los enlaces en su aplicación y luego colocar puntos de interrupción en las clases de asesores y ver qué se arrastra y suelta entre el escritorio y su aplicación, y luego codificar en consecuencia. HTH. – NVM

Cuestiones relacionadas