2011-02-01 14 views
7

Sto sviluppando un'applicazione simile a Dropbox e mostro i file remoti su un listview WPF. Voglio trascinare quegli elementi e rilasciarlo in Windows Explorer. Ho visto il codice come questo:WPF: trascina e rilascia i file virtuali in Esplora risorse di Windows

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

Ma come si potrebbe pensare, questi file non sono al sistema locale ancora, prima di copiying ho bisogno di connettersi al server, donwload e decomprimere i file. Come fa un client ftp.

Non so come farlo, ma mi chiedevo se c'è qualche evento "drop" o simile che posso gestire.

Grazie!

risposta

4

Questo frammento di codice:

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); 

Uso della classe linked dovrebbe funzionare. . Soluzione molto bella e facile.

+0

Si prega di dare una panoramica di ciò che dice il link. [Le risposte di solo collegamento sono scoraggiate] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) in quanto i collegamenti possono andare morti. Questo ha già, in una certa misura, dato che il contenuto originale è stato spostato. Sotto il vecchio URL, c'è ancora un puntatore al nuovo URL, ma chissà per quanto tempo rimarrà lì e per quanto tempo le informazioni saranno disponibili sul nuovo URL ... –

+0

Fornire un collegamento a una risposta non è una risposta, né è la qualità richiesta per una risposta delineata nelle politiche di utilizzo di StackOverflow. Per favore fornisci una risposta adeguata e inviterò. Grazie -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

Vai a questa serie di articoli. Questo dovrebbe aiutarti a iniziare.

EDIT: Vedere questo per 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

Questo esempio funziona bene tra UIElements ma non tra questi (Windows Desktop per esempio). Comunque, grazie per l'aiuto. – Morvader

+0

Funzionerà bene con il trascinamento della selezione tra desktop e app. Hai solo bisogno di una lezione DropTargetAdvisor appropriata. Permettetemi di modificare la mia risposta con un esempio – NVM

+0

Scusa ma è troppo lungo per spiegare l'intera cosa qui. L'unica cosa che devi cambiare è l'implementazione di DropTargetAdvisor e DragSourceAdvisor in modo appropriato. Quello che puoi fare è fare ciò che i link fanno nella tua app e quindi inserire i punti di interruzione nelle classi di advisor e vedere cosa viene trascinato e rilasciato tra il desktop e la tua app e quindi codificare di conseguenza. HTH. – NVM

Problemi correlati