Silverlight 4's New Drag-and-Drop Support

13 Comments November 26, 2009

Another new feature of Silverlight 4 that will enable developers to build richer UIs is drag-and-drop file support. In Silverlight 3, you had to pop up an OpenFileDialog to allow the user to select files from the local file system and make them available to a Silverlight application. In Silverlight 4, OpenFileDialog still works, but there is an alternative: let the user drag files from the operating system shell and drop them into a Silverlight application. The app can then consume the files in much the same way that it consumes files offered through OpenFileDialog.

To demonstrate the mechanics of Silverlight drop targeting, I built a sample that lets you open image files using drag-and-drop. Here's what the app looked like after I grabbed a bunch of JPEGs from My Pictures and dropped them into the running application:

DragDropDemo 

At startup, the application registers a handler for the new Drop event attached to the UIElement class, making the LayoutRoot Grid a drop target:

// Register a handler for Drop events

LayoutRoot.Drop += new DragEventHandler(LayoutRoot_Drop);

When one or more files are dropped into the Grid, LayoutRoot_Drop inserts the FileInfo objects representing the dropped files into a System.Collections.Generic.Queue:

// Queue the FileInfo objects representing dropped files

if (e.Data != null)

{

    FileInfo[] files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];

 

    foreach (FileInfo fi in files)

    {

        _files.Enqueue(fi);

    }

}

Later, a CompositionTarget.Rendering event handler dequeues the FileInfo objects and processes them one at a time (one FileInfo object per CompositionTarget.Rendering event), turning them into XAML Image objects with Borders around them:

if (_files.Count != 0)

{

    // Create a photo

    FileInfo fi = _files.Dequeue();

    CreatePhoto(fi);

}

The reason for using CompositionTarget.Rendering is that images have to be decoded and created on the application's UI thread. By processing one FileInfo object and returning, the event handler hands control back to Silverlight so the rendering engine can render the photo that was just added to the scene.

To enable applications to support drag-and-drop, Silverlight 4 adds four new events named DragEnter, DragOver, Drop, and DragLeave to the UIElement class. Therefore, any visual element can be a drop target. In non-Silverlight applications, you can use the IDataObject passed to these event handlers to determine what type of data is being offered. In Silverlight, however, you can only query the IDataObject in handlers for Drop events. Still, you could use the other events to perform drop-target highlighting or other UI-related chores when a cursor carrying a payload enters a drop target.

Another facet of the drag-and-drop story is the new UIElement.AllowDrop property. In order for an object to accept drops, this property must be set to true. That's why my sample application declares the LayoutRoot grid this way:

<Grid x:Name="LayoutRoot" AllowDrop="True">

You can download the source code and try it for yourself. Have fun dropping files!


13 Comments

  • Gravatar Image
    Rodrigo D&#237;az Concha November 26, 2009 1:30 PM

    Jeff, great example. Just a quick note: Drag and Drop support is available even on sandboxes applications (in-browser).

    Cheers!

  • Gravatar Image
    Mick Ross November 26, 2009 2:40 PM

    AFAIK Drag & Drop is not limited to OOB applications nor it requires permissions elevation.

  • Gravatar Image
    jprosise November 26, 2009 3:56 PM

    You are so right! I've updated the text (and the download) accordingly.

  • Gravatar Image
    Community Blogs January 18, 2010 5:52 AM

    Introduction Some years ago (pre-silverlight times) a client ask me for a weird requirement…he wanted

  • Gravatar Image
    FESTA LAUREA ROMA July 2, 2010 1:40 AM

    Thank you for sharing all this great information

  • Gravatar Image
    ss August 9, 2010 6:36 AM

    good tutorial

  • Gravatar Image
    David Gwyer September 5, 2010 8:29 AM

    Thanks for the demo Jeff, this is a great new feature of Silverlight 4!

  • Gravatar Image
    Cornflake September 17, 2010 8:08 AM

    Very Nice Sample

    Can you give a sample code for Drag Drop Files from Silverlight to Filesystem too?
    It's the way reverse

  • Gravatar Image
    SFP February 8, 2011 5:42 AM

    What`s right way to do this, if I have Navigation Silverlight 4 App and I don`t want that whole application has drag and drop feature.

    I have only one page that could be drop area. Problem is that only mainpage is getting drop event even I enabled it in contained page and grid inside that page.

  • Gravatar Image
    Lou September 29, 2011 7:32 PM

    Thanks for the great post and demo app.

  • Gravatar Image
    Mohan Sharm February 18, 2012 8:01 AM

    Great article, Please add google Plus icon to plus one it publicly. Very illustrative and working demo. Nice...

  • Gravatar Image
    deepak sahu February 23, 2012 10:00 AM

    In my application I am invoking a PopUp by

    Popup pop = new Popup; then i add this:: pop.child(page); where "page" is the instance of a XAML page which is of type ChildWindow. Now when the popup shows up on my MainPage, it becomes Non-Modal just like I want it to be!! But the problem is, the popup window is not draggable through out the Mainpage. I know that the popup appears within the Boundaries of a Silverlight control hosted in a browser. And It's not a true window. But still my popup is not draggable within its boundaries.. Am i missing some declarations which define the draggable region of a popup control OR is it the ChildWindow which needs to be configured ??

  • Gravatar Image
    StackOverflow user420667 March 18, 2012 12:55 PM

    I am having a fair degree of difficulty playing video off of the client's machine. I thought maybe you would know how to do this given your ability to do it with pictures. Here is my code that appears to fail:
    http://stackoverflow.com/questions/9649164/silverlight-dynamically-play-video-from-clients-machine
    I believe that it may be a problem with video needing to be "resourced" before it can be played.

    Thank you very much in advance.

Have a Comment?

Archives

Tags

Blogs