8

I'm developing an application similar to dropbox and i show the remote files on a WPF listview. I want to drag those elements and drop it into windows explorer. I've seen code like this:

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

But as you may think, those file are not at the local system yet, before copiying them I need to connect to server, donwload and unzip the files. Like a ftp client does.

I dont how to do it but i was wondering if there is any "drop" event or similiar that i can handle.

Thanks!

Morvader
  • 2,317
  • 3
  • 31
  • 44

2 Answers2

5

This snippet:

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

Using the class linked should work. . Very nice and easy solution.

Morvader
  • 2,317
  • 3
  • 31
  • 44
  • Please give an overview of what the link says. [Link-only answers are discouraged](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) as links can go dead. This one already has, to some extent, given that the original contents was moved. Under the old URL, there is currently still a pointer to the new URL, but who knows for how long that will remain there, and for how long the information will be available on the new URL ... – O. R. Mapper Jan 14 '15 at 23:32
  • Providing a link to an answer is not an answer, nor is it the quality required of an answer outlined in the StackOverflow usage policies. Please provide a proper answer and I will upvote. Thanks -AMR – DotNetRussell Aug 26 '15 at 13:35
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

See this series of articles. This should help you get started.

EDIT: See this for an amplementation of the 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)
     {
     }
DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
NVM
  • 5,442
  • 4
  • 41
  • 61
  • This examples works fine between UIElements but not out of them (Windows Desktop for example). Anyway, thanks for helping. – Morvader Feb 01 '11 at 12:14
  • It will work fine with drag and drop between the desktop and your app. You just need an appropriate DropTargetAdvisor class. Let me edit my answer with an example – NVM Feb 01 '11 at 12:24
  • Sorry but its just too long to explain the whole thing here. The only thing you need to change is the implementation of the DropTargetAdvisor and DragSourceAdvisor appropriately. What you can do is to do what the links do in your app and then put breakpoints in the advisor classes and see what gets dragged and dropped between the desktop and your app and then code accordingly. HTH. – NVM Feb 01 '11 at 12:32
  • I have an app which uses this approach to drag an image file from the desktop onto a canvas in my app. – NVM Feb 01 '11 at 12:34
  • 1
    i get you, but i think its much easier to drag from desktop into wpf element with "allow drop" propperty than drop INTO desktop a wpf element. Thats where im lost. Thanks for your interenst. – Morvader Feb 01 '11 at 12:50
  • See the edited answer. I dont see why the reverse is any different. As long as you set the correct dataobject when dragging it will work the same. Infact I just checked. My app uses the approach to drag image files from and to the desktop both ways. – NVM Feb 01 '11 at 12:59
  • 1
    I saw that you use "fileList.Add(imageVM.ImagePath);" so i assume that those images are accesible from your local system. My problem is that the files are not actually in my system, they are in a remote server, so i must perform several actions before copiying them to my "explorer". Thats why i needed to capture the drop event, just to know the moment i have to star processing remote files. I appreciate your effort. – Morvader Feb 02 '11 at 14:44