Home > Posts > HowTo: Drop files onto Silverlight controls

HowTo: Drop files onto Silverlight controls

I was recently adding drop-files support to ClipFlair Studio, so I had to do some research on the related API that is available to Silverlight apps.

Silverlight supports a limited set of Drag-and-Drop interaction with the operating system (supposedly for security reasons, but most probably because of the classic cross-platform implementation pains).

For example it allows you to drop a collections of file objects from the operating system’s file explorer (or other similar application) onto a Silverlight drop target, but not the other way around.

Also, it doesn’t allow dropping other flavors of content, like text, images etc., only collections of file objects.

To allow dropping files onto a Silverlight control you set AllowDrop property to true and handle the Drop and optionally the DragEnter/DragOver/DragLeave events to provide visual feedback during the drop operation (mostly when over the drop target, unless you do Mouse Capturing).

<RichTextBox
  x:Name="rtb"
  …
  AllowDrop="True" 
  Drop="rtb_Drop"
  DragEnter="rtb_DragEnter"
  DragOver="rtb_DragOver"
  DragLeave="rtb_DragLeave"

  />

 

  #region DragAndDrop

    private void rtb_Drop(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "Normal", true);

      //the Drop event passes in an array of FileInfo objects for the list of files that were selected and drag-dropped onto the RichTextBox.
      if (e.Data == null)
        return;

     IDataObject f = e.Data as IDataObject;
      if (f != null) //checks if the dropped objects are files

      {
        object data = f.GetData(DataFormats.FileDrop); //Silverlight only supports FileDrop
        FileInfo[] files = data as FileInfo[]; //…GetData returns null if format is not supported

        e.Handled = true;

        if (files != null)

          //Walk through the list of FileInfo objects of the selected and drag-dropped files and parse the .txt and .docx files
          //and insert their content in the RichTextBox.
          foreach (FileInfo file in files)
            Load(file, false);
      }

    }

    private void rtb_DragEnter(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "DragOver", true);
      e.Handled = true;
    }
   
    private void rtb_DragOver(object sender, System.Windows.DragEventArgs e)
    {
      e.Handled = true;
      //NOP
    }

    private void rtb_DragLeave(object sender, System.Windows.DragEventArgs e)
    {
      VisualStateManager.GoToState(this, "Normal", true);
      e.Handled = true;
    }

    #endregion

 

For the visual feedback you can use VisualStateManager and respective VisualStates at say a Grid that wraps the drop target in the XAML layout.

<Grid x:Name="LayoutRoot">
   <VisualStateManager.VisualStateGroups>
     <VisualStateGroup x:Name="DragStates">
       <VisualStateGroup.Transitions>
         <VisualTransition GeneratedDuration="0:0:0.3">
           <VisualTransition.GeneratedEasingFunction>
             <CircleEase EasingMode="EaseIn"/>
           </VisualTransition.GeneratedEasingFunction>
         </VisualTransition>
       </VisualStateGroup.Transitions>
       <VisualState x:Name="Normal"/>
       <VisualState x:Name="DragOver">
         <Storyboard>
           <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" Storyboard.TargetName="rtb">
             <EasingColorKeyFrame KeyTime="0" Value="#FFFFF7D1"/>
           </ColorAnimationUsingKeyFrames>
         </Storyboard>
       </VisualState>
     </VisualStateGroup>
   </VisualStateManager.VisualStateGroups>

 

Note that on MacOS-X Safari doesn’t pass drop events automatically to plugins and you have to catch them via Javascript and pass them to Silverlight, plus I’ve read that in MacOS-X Firefox doesn’t support this at all.

Even worse, Microsoft’s workaround article has a typo in the Javascript (should call dragDrop instead of drop) and there is a chance it doesn’t work in latest version of Safari. For more see:

http://msdn.microsoft.com/en-us/library/ee670998%28v=vs.95%29.aspx

http://social.msdn.microsoft.com/Forums/silverlight/en-US/42a6b672-7d26-4690-be80-2149da755020/silverlight-4-detect-file-drop-event-on-mac?forum=silverlightarchieve&prof=required

http://community.rightpoint.com/blogs/viewpoint/archive/2011/03/27/silverlight-4-file-drag-and-drop-on-firefox-on-mac.aspx

http://www.telerik.com/forums/dropping-files-using-safari-on-mac (this says one can use HTML5 events and the Silverlight HTML/Javascript Bridge to notify Silverlight)

http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: