Home > Silverlight > Silverlight Drag and Drop API

Silverlight Drag and Drop API

November 28th, 2009 Leave a comment Go to comments

Introduction

Drag and drop is a common UX paradigm and a top requested feature. In Silverlight 4 Beta, we introduced a basic set of API to enable the most common scenario of dragging pictures files and dropping them to Silverlight applications, and we designed the API to allow us to expose more drag and drop functionalities down the road without API change, hopefully.

API

Below is the core of the new API:

namespace System.Windows
{
public abstract class UIElement : DependencyObject
{
// Fields
public static readonly DependencyProperty AllowDropProperty;

// Events
public event DragEventHandler DragEnter;
public event DragEventHandler DragLeave;
public event DragEventHandler DragOver;
public event DragEventHandler Drop;

// Properties
public bool AllowDrop { get; set; }
}

public delegate void DragEventHandler(object sender, DragEventArgs e);

public sealed class DragEventArgs : RoutedEventArgs
{
// Methods
public Point GetPosition(UIElement relativeTo);

// Properties
public IDataObject Data { [SecuritySafeCritical] get; }
public bool Handled { get; set; }
}
}

namespace System.Windows.Controls
{
public abstract class Control : FrameworkElement
{
protected virtual void OnDragEnter(DragEventArgs e);
protected virtual void OnDragLeave(DragEventArgs e);
protected virtual void OnDragOver(DragEventArgs e);
protected virtual void OnDrop(DragEventArgs e);
}
}

  • AllowDrop: this is dependency property, indicating whether an element is a drop target.
  • DragEnter, DragLeave, DragOver & Drop: these are routed events. They bubble up, and fire only on elements with AllowDrop set to true.
  • OnDragEnter, OnDragLeave, OnDragOver & OnDrop: these are protected virtual functions for subclasses to override. 
  • DragEventArgs: this class allows drop target event handlers or method overrides to access the data being dragged or dropped.

Usage

There are primarily two ways to use Silverlight’s drag and drop API:

  • Silverlight applications can handle those drop target events and process the files dropped in the event handlers.
  • Silverlight controls can override those drop target virtual functions to process the data being dragged and dropped, and enable themselves to be drop targets.

Limitations

The drag and drop functionality shipped in Silverlight 4 Beta only enables the most common scenario: Silverlight plugin as a file drop target. Please notice the following limitations with current implementation:

  • there is no drop source support (QueryContinueDrag & GiveFeedback).
  • there is no DragDropEffects or DragDropKeyStates in DragEventArgs.
  • there is no visual for the dragged object or DragDropEffects.
  • only file drag and drop is supported:
    • all drop target events fire only when files are being dragged and dropped.
    • IDataObject, DataObject and DragEventArgs.Data support only one format: “FileDrop”, and the data is of type FileInfo[].
  • most of IDataObject methods throw NotImplementedException.
  • for drag and drop to work on Windows, Silverlight plugin must be windowed. In another word, if <param name="windowless" value="true"/> is specified, drop events won’t fire.
  • since Silverlight plugin on Mac is always windowless, you need to hook up JavaScript drop events to trigger Silverlight drop events. In another word, if you want your Silverlight application to support file drop on Mac as well as Windows, you will need to add following script and Silverlight plugin attributes to the hosting html or aspx page:
    <!-- add following script before end of HEAD tag -->
    <script type="text/javascript">
    function handleDragEnter(oEvent) {
    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragEnter(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }

    function handleDragLeave(oEvent) {
    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragLeave(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }

    function handleDragOver(oEvent) {
    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragOver(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }

    function handleDropEvent(oEvent) {

    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragDrop(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }
    </script>
    <!-- use JavaScript drop target events to trigger Silverlight's drop target events -->
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"
    id="silverlightControl" ondragenter="handleDragEnter(event)" ondragover="handleDragOver(event)"
    ondragleave="handleDragLeave(event)" ondrop="handleDropEvent(event)" >

  • DragEventArgs.Data is only accessible in Drop event. Accessing DragEventArgs.Data in DragEnter, DragOver and DragLeave may cause SecurityException. And accessing Directory, DirectoryName or FullName property of the FileInfo object from DragEventArgs.Data may cause ArgumentNullException. 

    Demo App

    Below is a demo app:

  • the top left nested grids use drop target event handler to display DragEventArgs info.
  • the top right nested grids contain an ImageDropTarget user control, which overrides OnDrop method to render the dropped file if it is an image.
  • the bottom listbox shows the sequence of drop target events, their bubbling up, and DragEventArgs info.

    Click to run DragDropDemo if you have Silverlight 4 Beta installed.

    you can find the complete source here.

    Feedback

    While we are excited to add drag and drop to Silverlight, we know there are a lot to finish/improve, and what we released is just a Beta. As always, your feedback is highly appreciated, and will be used as an important data point to help us prioritize the work. Thanks!

     

    Technorati Tags: ,

    Share and Enjoy:

    • Print
    • email
    • RSS
    • Twitter
    • TwitThis
    • del.icio.us
    • LinkedIn
    • Technorati
    • Facebook
    • Google Bookmarks
    • Live
    • MySpace
    • QQ书签
    1. December 25th, 2009 at 21:47 | #1

      @Rudy
      I also want to know.thank you!
      regards
      silverlight

    2. December 19th, 2009 at 11:04 | #2

      @Rudy
      Please see my other replies. The Silverlight Toolkit already has ListBoxDragDropTarget, so you can drag from ListBox. You do need to implement your own Canvas drag drop target container, for now.

    3. December 19th, 2009 at 10:22 | #3

      @GB
      Right now SL4 runtime only supports SL plugin as a file drop target, and only exposes drop target properties (AllDrop) and events (DragEnter/Move/Leave, Drop), but not drag source events (GiveFeedback, QueryContinueDrag). It is not fully extensible via IDataObject either. If you can’t wait, your best chance for now is to look at the toolkit implementation, which allows drag and drop to and from DataGrid within SL plugin. The code is in DataGridDragDropTarget.cs under source\Controls.Data.Toolkit project. Thanks.

    4. GB
      December 13th, 2009 at 17:04 | #4

      hi, i want to know how to implement to drag&drop on datagrid?

    5. Rudy
      November 29th, 2009 at 10:46 | #5

      I would like to know if there are any way to implement drag & drop objects (icons) from list box to canvas?

      Regards

      Rudy

    6. November 28th, 2009 at 09:59 | #6

      @Brice Prunier
      Yes. Jafar has implemented almost complete, WPF compatible, drag and drop functionality for both Silverlight 3 and Silverlight 4. It is shipped as part of Silverlight Toolkit. I highly recommend checking out his blog posts for more information.

      Please notice a key differences between the two drag and drop implementations: the Toolkit version is implemented on top of runtime, so it requires a *DragDropTarget container, and works only between elements within a Silverlight plugin control. The Toolkit implementation leverages runtime drag and drop API when it can, like in Silverlight 4 Toolkit, Microsoft.Windows.DragDrop.AllowDrop uses UIElement.AllowDrop property. While the runtime exposes drop target events for all UIElement, the Toolkit implementation already handles those events for important controls like DataGrid, ListBox and TreeView, so it is really easy to use. We’ve made sure the APIs are as compatible as possible, so people can use both together for now, and migrate to runtime implementation rather easily as runtime exposes more drag and drop functionalities. This is also the general approach of Silverlight Toolkit, as I called out in earlier post Silverlight Controls.

    7. Brice Prunier
      November 28th, 2009 at 07:55 | #7

      SL4 Toolkit (System.Windows.Controls.Toolkit) provides more higher level DragDrop implementations for intra Silverligth Drag & Drop.
      Not all cases are currently supported by SL 4 Toolkit but you can easely create your own from the abstract class DragDropTarget.

      regards

    1. No trackbacks yet.