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!