Click here to Skip to main content
6,633,937 members and growing! (20,662 online)
Email Password   helpLost your password?
Languages » C# » Windows Forms     Intermediate License: The Code Project Open License (CPOL)

Drag and Drop files from Windows Explorer to Windows Form

By Alex Fr

How to open files dropped from Explorer to a Windows Form
C#, Windows, .NET 1.0, Dev
Posted:31 Jan 2003
Views:104,558
Bookmarked:100 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
31 votes for this article.
Popularity: 6.88 Rating: 4.61 out of 5
1 vote, 3.2%
1

2
1 vote, 3.2%
3
8 votes, 25.8%
4
21 votes, 67.7%
5

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)

About the Author

Alex Fr


Member

Occupation: Software Developer
Location: Israel Israel

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 26 (Total in Forum: 26) (Refresh)FirstPrevNext
GeneralDrag and Drop files from Outlook PinmemberDmitry Kikhtev17:49 1 Nov '09  
Generaldrag and drop on webbrowser control? PinmemberMember 41792308:13 28 Oct '09  
GeneralProblems with Vista? Pinmemberyasaralper0:06 9 Jun '08  
GeneralRe: Problems with Vista? Pinmemberahumeniy19:55 10 Jul '08  
GeneralHow can I use this so that it includes the child folders as well? PinmemberDave Sheets8:19 7 Apr '08  
GeneralRe: How can I use this so that it includes the child folders as well? PinmemberAlex Fr7:57 8 Apr '08  
QuestionAdding Drag-and-Drop capability to an existing Windows Forms application [modified] Pinmembersumibell2:27 5 Mar '07  
GeneralUserControl Pinmembercool_ic3b3rg11:53 14 Aug '06  
GeneralRe: UserControl PinmemberAlex Fr23:14 14 Aug '06  
GeneralRe: UserControl Pinmembernetbeaz9:00 27 Jan '07  
GeneralRe: UserControl Pinmembergaddlord22:07 11 Jul '07  
GeneralSome sort of shell structure PinmemberAndrewVos23:32 16 Aug '05  
GeneralProblem dragging system drive Pinmembernagarsoft7:09 4 Jun '05  
GeneralRe: Problem dragging system drive PinmemberAlex Fr7:28 4 Jun '05  
GeneralHow to drag a String into the windows explorer in order to make him save a file ? PinmemberHurricane_san4:50 25 May '05  
GeneralHow to Drop Shortcut from desktop on MyForm Pinmemberhninel4:03 18 May '05  
GeneralHow to Drag from app, Drop into Windows Explorer? PinsussAnonymous15:59 9 Feb '04  
GeneralRe: How to Drag from app, Drop into Windows Explorer? PinsussAnonymous21:07 4 May '04  
GeneralRe: How to Drag from app, Drop into Windows Explorer? PinmemberJeremy Solt4:26 29 Oct '04  
GeneralRe: How to Drag from app, Drop into Windows Explorer? PinmemberMichaelgor6:56 1 Sep '06  
AnswerRe: How to Drag from app, Drop into Windows Explorer? PinmemberJeremy Solt7:02 9 Sep '06  
Generalonto the program icon? PinsussAnonymous5:19 15 Jun '03  
GeneralRe: onto the program icon? PinmemberAlex Farber4:07 19 Jun '03  
GeneralRe: onto the program icon? PinmemberFlyboy_yes19:43 6 Apr '05  
GeneralWhen Invoking... PineditorHeath Stewart3:39 4 Feb '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 31 Jan 2003
Editor: Chris Maunder
Copyright 2003 by Alex Fr
Everything else Copyright © CodeProject, 1999-2009
Web20 | Advertise on the Code Project