Click here to Skip to main content
Click here to Skip to main content

Drag and Drop files from Windows Explorer to Windows Form

, 31 Jan 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
How to open files dropped from Explorer to a Windows Form

Introduction

If we have a Windows Forms application which has File -> Open functionality, adding a few lines of code allows the user to open files dragged from the Windows Explorer. This article describes how to add this feature to your application.

Adding Drag-and-Drop capability to an existing Windows Forms application

Suppose we have simple image viewer program (demo project DropFiles). When tje user selects File -> Open, it shows the 'Open File' dialog:

private void mnuFileOpen_Click(object sender, System.EventArgs e)
{
    // Show Open File dialog
    OpenFileDialog openDlg = new OpenFileDialog();
    openDlg.Filter  = "Jpeg files (*.jpg)|*.jpg|Bitmap files (*.bmp)|"
                      + *.bmp|All Files (*.*)|*.*";

    openDlg.FileName = "" ;
    openDlg.CheckFileExists = true;
    openDlg.CheckPathExists = true;

    if ( openDlg.ShowDialog() != DialogResult.OK )
        return;

    OpenFile(openDlg.FileName);
}
The function OpenFile loads the image file to a class member Bitmap m_Bitmap, and the Paint event handler shows this bitmap on the screen:
private Bitmap m_Bitmap;

private void OpenFile(string sFile)
{
    Bitmap bmp;

    try
    {
        // load bitmap from file
        bmp = (Bitmap)Bitmap.FromFile(sFile, false);

        if ( bmp != null )
        {
            // Keep bitmap in class member
            m_Bitmap = (Bitmap) bmp.Clone();

            // Set Autoscroll properties
            this.AutoScroll = true;

            this.AutoScrollMinSize = new Size (
                    m_Bitmap.Width, 
                    m_Bitmap.Height);
            
            // draw image
            Invalidate();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(
            this,
            ex.Message,
            "Error loading from file");
    }
}

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    if ( m_Bitmap != null )
    {
        e.Graphics.DrawImage(
            m_Bitmap, 
            new Rectangle(this.AutoScrollPosition.X, 
            this.AutoScrollPosition.Y, 
            m_Bitmap.Width, 
            m_Bitmap.Height));
    }
}
To open files dropped from the Windows Explorer we need to set the form AllowDrop property to true. After this add the DragEnter and DragDrop event handlers.

DragEnter handler is simple - program accepts only files:

private void Form1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop)) 
        e.Effect = DragDropEffects.Copy;
    else
        e.Effect = DragDropEffects.None;
}

The DragEventArgs.GetData function returns an IDataObject interface that contains the data associated with this DragDrop event. When a file or files are dropped from Explorer to the form, IDataObject contains an array of file names. If one file is dropped, the array contains one element. All the time the DragDrop event handler is working, the Windows Explorer instance is not responding. Therefore, we need to call the OpenFile function asynchronously. This is done using the BeginInvoke function and a delegate pointing to OpenFile. It is a good idea also to move the form to the foreground after dropping file to it.

private delegate void DelegateOpenFile(String s);           // type
private DelegateOpenFile m_DelegateOpenFile;                // instance

private void Form1_Load(object sender, System.EventArgs e)
{
    // create delegate used for asynchronous call
    m_DelegateOpenFile = new DelegateOpenFile(this.OpenFile);
}


private void Form1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
    try
    {
        Array a = (Array)e.Data.GetData(DataFormats.FileDrop);

        if ( a != null )
        {
            // Extract string from first array element
            // (ignore all files except first if number of files are dropped).
            string s = a.GetValue(0).ToString();

            // Call OpenFile asynchronously.
            // Explorer instance from which file is dropped is not responding
            // all the time when DragDrop handler is active, so we need to return
            // immidiately (especially if OpenFile shows MessageBox).

            this.BeginInvoke(m_DelegateOpenFile, new Object[] {s});

            this.Activate();        // in the case Explorer overlaps this form
        }
    }
    catch (Exception ex)
    {
        Trace.WriteLine("Error in DragDrop function: " + ex.Message);

        // don't show MessageBox here - Explorer is waiting !
    }
}
This is all we need to implement Drag-and-Drop capability in Windows Forms application. However, good programming style requires writing the wrapper class which encapsulates this feature.

Using the DragDropManager class

The second demo project DropFiles1 opens files dropped from Explorer using helper class DragDropManager. The project is very simple - it allows you to open one or more files and shows the file names in listbox. It has mnuFileOpen_Click function which shows Open File dialog and calls OpenFiles(Array a) passing array of file names selected by user.

Form that uses DragDropManager should implement IDropFileTarget interface defined in the same file as DragDropManager:

public interface IDropFileTarget
{
    void OpenFiles(System.Array a);
}
So, main form is derived from IDropFileTarget:
public class Form1 : System.Windows.Forms.Form, IDropFileTarget
and has OpenFiles function which opens files selected from File - Open dialog or dropped from Windows Explorer:
public void OpenFiles(Array a)
{
    // If our application can open only one file, we can process
    // here only first element of array or give some error message
    // in the case array contains more than one file.
    //
    // In this sample I allow to open number of files showing 
    // their names in list box.

    string sError = "";
    string sFile;

    lstFiles.Items.Clear();

    // process all files in array
    for ( int i = 0; i < a.Length; i++ )
    {
        sFile = a.GetValue(i).ToString();           // file name

        // Check file name
        // (Let's say we don't accept non-existing files or directories)
        FileInfo info = new FileInfo(sFile);

        if ( ! info.Exists )
        {
            sError += "\nIncorrect file name: " + sFile;
        }
        else
        {
            lstFiles.Items.Add(sFile);
        }
    }

    if ( sError.Length > 0 )
        MessageBox.Show(this, sError, "Open File Error");
}
The Form has the member
private DragDropManager m_DragDropManager;
which is initialized in Load event handler:
private void Form1_Load(object sender, System.EventArgs e)
{
    m_DragDropManager = new DragDropManager();
    m_DragDropManager.Parent = this;
}
So, the steps that should be done for using DragDropManager class in Windows Form are:
- Derive the form from IDropFileTarget interface;
- Implement IDropFileTarget interface adding function OpenFiles(Array a);
- Add member of DragDropManager type to the form;
- Initialize it setting Parent property to form reference.

Class DragDropManager

This class keeps reference to owner form in class member and has delegate used for asynchronous call to the form:
private Form m_parent;          // reference to owner form

private delegate void DelegateOpenFiles(Array a);           // type
private DelegateOpenFiles m_DelegateOpenFiles;              // instance
Initialization is done when client sets Parent property:
public Form Parent
{
    set
    {
        m_parent = value;               // keep reference to owner form

        // Check if owner form implements IDropFileTarget interface
        if ( ! ( m_parent is IDropFileTarget ) )
        {
            throw new Exception(
                "DragDropManager: Parent form doesn't implement IDropFileTarget interface");
        }

        // create delegate used for asynchronous call
        m_DelegateOpenFiles = new DelegateOpenFiles(((IDropFileTarget)m_parent).OpenFiles);

        // ensure that owner form allows dropping
        m_parent.AllowDrop = true;

        // subscribe to owner form's drag-drop events
        m_parent.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnDragEnter);
        m_parent.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnDragDrop);
    }
}
OnDragEnter and OnDragDrop are subscribed to owner form DragEnter and DragDrop events:
private void OnDragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop)) 
        e.Effect = DragDropEffects.Copy;
    else
        e.Effect = DragDropEffects.None;
}

private void OnDragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
    try
    {
        Array a = (Array)e.Data.GetData(DataFormats.FileDrop);

        if ( a != null )
        {
            // Call owner's OpenFiles asynchronously.

            m_parent.BeginInvoke(m_DelegateOpenFiles, new Object[] {a});

            m_parent.Activate();        // in the case Explorer overlaps owner form
        }
    }
    catch (Exception ex)
    {
        Trace.WriteLine("Error in DragDropManager.OnDragDrop function: " + ex.Message);
    }
}

Acknowledgements

  1. Using helper class with subscribing to owner form events. Joel Matthias.
    http://www.codeproject.com/csharp/restoreformstate.asp
  2. Using form AutoScroll properties. Christian Graus.
    http://www.codeproject.com/cs/media/csharpgraphicfilters11.asp

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alex Fr
Software Developer
Israel Israel
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermanoj kumar choubey28-Nov-12 19:31 
QuestionWindows Explorer lock, freezes even if using BeginInvoke PinmemberRolf Kristensen5-Oct-11 10:22 
QuestionNot working when start my application As administrator? Pinmemberdejan19dejan1921-Sep-11 5:55 
AnswerRe: Not working when start my application As administrator? PinmemberRolf Kristensen5-Oct-11 10:18 
GeneralMy vote of 5 Pinmemberzoli7712310-Aug-11 12:54 
GeneralMy vote of 5 PinmemberMember 791404412-Jul-11 0:16 
GeneralMy vote of 4 PinmemberRolf Kristensen13-Apr-11 11:55 
GeneralThanks, man, really gj... PinmemberJan Kurbanaliev2-Aug-10 20:31 
QuestionThank's man PinmemberAlireza Hajihasani19-Jul-10 23:39 
GeneralDrag and Drop files from Outlook PinmemberDmitry Kikhtev1-Nov-09 17:49 
Questiondrag and drop on webbrowser control? PinmemberMember 417923028-Oct-09 8:13 
QuestionProblems with Vista? Pinmemberyasaralper9-Jun-08 0:06 
AnswerRe: Problems with Vista? Pinmemberahumeniy10-Jul-08 19:55 
GeneralRe: Problems with Vista? - Thank You! Pinmembergrcook001-Jan-11 12:50 
QuestionHow can I use this so that it includes the child folders as well? PinmemberDave Sheets7-Apr-08 8:19 
AnswerRe: How can I use this so that it includes the child folders as well? PinmemberAlex Fr8-Apr-08 7:57 
QuestionAdding Drag-and-Drop capability to an existing Windows Forms application [modified] Pinmembersumibell5-Mar-07 2:27 
GeneralUserControl Pinmembercool_ic3b3rg14-Aug-06 11:53 
GeneralRe: UserControl PinmemberAlex Fr14-Aug-06 23:14 
GeneralRe: UserControl Pinmembernetbeaz27-Jan-07 9:00 
GeneralRe: UserControl Pinmembergaddlord11-Jul-07 22:07 
GeneralSome sort of shell structure PinmemberAndrewVos16-Aug-05 23:32 
GeneralProblem dragging system drive Pinmembernagarsoft4-Jun-05 7:09 
GeneralRe: Problem dragging system drive PinmemberAlex Fr4-Jun-05 7:28 
QuestionHow to drag a String into the windows explorer in order to make him save a file ? PinmemberHurricane_san25-May-05 4:50 
QuestionHow to Drop Shortcut from desktop on MyForm Pinmemberhninel18-May-05 4:03 
QuestionHow to Drag from app, Drop into Windows Explorer? PinsussAnonymous9-Feb-04 15:59 
AnswerRe: How to Drag from app, Drop into Windows Explorer? PinsussAnonymous4-May-04 21:07 
AnswerRe: How to Drag from app, Drop into Windows Explorer? PinmemberJeremy Solt29-Oct-04 4:26 
GeneralRe: How to Drag from app, Drop into Windows Explorer? PinmemberMichaelgor1-Sep-06 6:56 
AnswerRe: How to Drag from app, Drop into Windows Explorer? PinmemberJeremy Solt9-Sep-06 7:02 
Questiononto the program icon? PinsussAnonymous15-Jun-03 5:19 
AnswerRe: onto the program icon? PinmemberAlex Farber19-Jun-03 4:07 
GeneralRe: onto the program icon? PinmemberFlyboy_yes6-Apr-05 19:43 
GeneralWhen Invoking... PineditorHeath Stewart4-Feb-03 3:39 
GeneralRe: When Invoking... PinmemberAlex Farber4-Feb-03 4:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411023.1 | Last Updated 1 Feb 2003
Article Copyright 2003 by Alex Fr
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid