How do I drag and drop files into an application? - c#

I've seen this done in Borland's Turbo C++ environment, but I'm not sure how to go about it for a C# application I'm working on. Are there best practices or gotchas to look out for?

Some sample code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
}
}

Be aware of windows vista/windows 7 security rights - if you are running Visual Studio as administrator, you will not be able to drag files from a non-administrator explorer window into your program when you run it from within visual studio. The drag related events will not even fire!

In Windows Forms, set the control's AllowDrop property, then listen for DragEnter event and DragDrop event.
When the DragEnter event fires, set the argument's AllowedEffect to something other than none (e.g. e.Effect = DragDropEffects.Move).
When the DragDrop event fires, you'll get a list of strings. Each string is the full path to the file being dropped.

You need to be aware of a gotcha. Any class that you pass around as the DataObject in the drag/drop operation has to be Serializable. So if you try and pass an object, and it is not working, ensure it can be serialized as that is almost certainly the problem. This has caught me out a couple of times!

Yet another gotcha:
The framework code that calls the Drag-events swallow all exceptions. You might think your event code is running smoothly, while it is gushing exceptions all over the place. You can't see them because the framework steals them.
That's why I always put a try/catch in these event handlers, just so I know if they throw any exceptions. I usually put a Debugger.Break(); in the catch part.
Before release, after testing, if everything seems to behave, I remove or replace these with real exception handling.

Here is something I used to drop files and/or folders full of files. In my case I was filtering for *.dwg files only and chose to include all subfolders.
fileList is an IEnumerable or similar In my case was bound to a WPF control...
var fileList = (IList)FileList.ItemsSource;
See https://stackoverflow.com/a/19954958/492 for details of that trick.
The drop Handler ...
private void FileList_OnDrop(object sender, DragEventArgs e)
{
var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
var files = dropped.ToList();
if (!files.Any())
return;
foreach (string drop in dropped)
if (Directory.Exists(drop))
files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));
foreach (string file in files)
{
if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
fileList.Add(file);
}
}

Another common gotcha is thinking you can ignore the Form DragOver (or DragEnter) events. I typically use the Form's DragOver event to set the AllowedEffect, and then a specific control's DragDrop event to handle the dropped data.

The solution of Judah Himango and Hans Passant is available in the Designer (I am currently using VS2015):

You can implement Drag&Drop in WinForms and WPF.
WinForm (Drag from app window)
You should add mousemove event:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e)
{
...
if (e.Button == MouseButtons.Left)
{
DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
}
...
}
WinForm (Drag to app window)
You should add DragDrop event:
private void YourElementControl_DragDrop(object sender, DragEventArgs e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}
Source with full code.

Note that for this to work, you also need to set the dragDropEffect within _drawEnter...
private void Form1_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("DragEnter!");
e.Effect = DragDropEffects.Copy;
}
Source: Drag and Drop not working in C# Winforms Application

Related

How can I Drag and Drop a File into a listBox and get the FilePath information in C#? [duplicate]

I've seen this done in Borland's Turbo C++ environment, but I'm not sure how to go about it for a C# application I'm working on. Are there best practices or gotchas to look out for?
Some sample code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
}
}
Be aware of windows vista/windows 7 security rights - if you are running Visual Studio as administrator, you will not be able to drag files from a non-administrator explorer window into your program when you run it from within visual studio. The drag related events will not even fire!
In Windows Forms, set the control's AllowDrop property, then listen for DragEnter event and DragDrop event.
When the DragEnter event fires, set the argument's AllowedEffect to something other than none (e.g. e.Effect = DragDropEffects.Move).
When the DragDrop event fires, you'll get a list of strings. Each string is the full path to the file being dropped.
You need to be aware of a gotcha. Any class that you pass around as the DataObject in the drag/drop operation has to be Serializable. So if you try and pass an object, and it is not working, ensure it can be serialized as that is almost certainly the problem. This has caught me out a couple of times!
Yet another gotcha:
The framework code that calls the Drag-events swallow all exceptions. You might think your event code is running smoothly, while it is gushing exceptions all over the place. You can't see them because the framework steals them.
That's why I always put a try/catch in these event handlers, just so I know if they throw any exceptions. I usually put a Debugger.Break(); in the catch part.
Before release, after testing, if everything seems to behave, I remove or replace these with real exception handling.
Here is something I used to drop files and/or folders full of files. In my case I was filtering for *.dwg files only and chose to include all subfolders.
fileList is an IEnumerable or similar In my case was bound to a WPF control...
var fileList = (IList)FileList.ItemsSource;
See https://stackoverflow.com/a/19954958/492 for details of that trick.
The drop Handler ...
private void FileList_OnDrop(object sender, DragEventArgs e)
{
var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
var files = dropped.ToList();
if (!files.Any())
return;
foreach (string drop in dropped)
if (Directory.Exists(drop))
files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));
foreach (string file in files)
{
if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
fileList.Add(file);
}
}
Another common gotcha is thinking you can ignore the Form DragOver (or DragEnter) events. I typically use the Form's DragOver event to set the AllowedEffect, and then a specific control's DragDrop event to handle the dropped data.
The solution of Judah Himango and Hans Passant is available in the Designer (I am currently using VS2015):
You can implement Drag&Drop in WinForms and WPF.
WinForm (Drag from app window)
You should add mousemove event:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e)
{
...
if (e.Button == MouseButtons.Left)
{
DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
}
...
}
WinForm (Drag to app window)
You should add DragDrop event:
private void YourElementControl_DragDrop(object sender, DragEventArgs e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}
Source with full code.
Note that for this to work, you also need to set the dragDropEffect within _drawEnter...
private void Form1_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("DragEnter!");
e.Effect = DragDropEffects.Copy;
}
Source: Drag and Drop not working in C# Winforms Application

How to load pictures from specified folder in winforms and how to drag these images to somewhere in forms [duplicate]

I've seen this done in Borland's Turbo C++ environment, but I'm not sure how to go about it for a C# application I'm working on. Are there best practices or gotchas to look out for?
Some sample code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
}
}
Be aware of windows vista/windows 7 security rights - if you are running Visual Studio as administrator, you will not be able to drag files from a non-administrator explorer window into your program when you run it from within visual studio. The drag related events will not even fire!
In Windows Forms, set the control's AllowDrop property, then listen for DragEnter event and DragDrop event.
When the DragEnter event fires, set the argument's AllowedEffect to something other than none (e.g. e.Effect = DragDropEffects.Move).
When the DragDrop event fires, you'll get a list of strings. Each string is the full path to the file being dropped.
You need to be aware of a gotcha. Any class that you pass around as the DataObject in the drag/drop operation has to be Serializable. So if you try and pass an object, and it is not working, ensure it can be serialized as that is almost certainly the problem. This has caught me out a couple of times!
Yet another gotcha:
The framework code that calls the Drag-events swallow all exceptions. You might think your event code is running smoothly, while it is gushing exceptions all over the place. You can't see them because the framework steals them.
That's why I always put a try/catch in these event handlers, just so I know if they throw any exceptions. I usually put a Debugger.Break(); in the catch part.
Before release, after testing, if everything seems to behave, I remove or replace these with real exception handling.
Here is something I used to drop files and/or folders full of files. In my case I was filtering for *.dwg files only and chose to include all subfolders.
fileList is an IEnumerable or similar In my case was bound to a WPF control...
var fileList = (IList)FileList.ItemsSource;
See https://stackoverflow.com/a/19954958/492 for details of that trick.
The drop Handler ...
private void FileList_OnDrop(object sender, DragEventArgs e)
{
var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
var files = dropped.ToList();
if (!files.Any())
return;
foreach (string drop in dropped)
if (Directory.Exists(drop))
files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));
foreach (string file in files)
{
if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
fileList.Add(file);
}
}
Another common gotcha is thinking you can ignore the Form DragOver (or DragEnter) events. I typically use the Form's DragOver event to set the AllowedEffect, and then a specific control's DragDrop event to handle the dropped data.
The solution of Judah Himango and Hans Passant is available in the Designer (I am currently using VS2015):
You can implement Drag&Drop in WinForms and WPF.
WinForm (Drag from app window)
You should add mousemove event:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e)
{
...
if (e.Button == MouseButtons.Left)
{
DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
}
...
}
WinForm (Drag to app window)
You should add DragDrop event:
private void YourElementControl_DragDrop(object sender, DragEventArgs e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}
Source with full code.
Note that for this to work, you also need to set the dragDropEffect within _drawEnter...
private void Form1_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("DragEnter!");
e.Effect = DragDropEffects.Copy;
}
Source: Drag and Drop not working in C# Winforms Application

Drag and Drop files in form [duplicate]

I've seen this done in Borland's Turbo C++ environment, but I'm not sure how to go about it for a C# application I'm working on. Are there best practices or gotchas to look out for?
Some sample code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
}
}
Be aware of windows vista/windows 7 security rights - if you are running Visual Studio as administrator, you will not be able to drag files from a non-administrator explorer window into your program when you run it from within visual studio. The drag related events will not even fire!
In Windows Forms, set the control's AllowDrop property, then listen for DragEnter event and DragDrop event.
When the DragEnter event fires, set the argument's AllowedEffect to something other than none (e.g. e.Effect = DragDropEffects.Move).
When the DragDrop event fires, you'll get a list of strings. Each string is the full path to the file being dropped.
You need to be aware of a gotcha. Any class that you pass around as the DataObject in the drag/drop operation has to be Serializable. So if you try and pass an object, and it is not working, ensure it can be serialized as that is almost certainly the problem. This has caught me out a couple of times!
Yet another gotcha:
The framework code that calls the Drag-events swallow all exceptions. You might think your event code is running smoothly, while it is gushing exceptions all over the place. You can't see them because the framework steals them.
That's why I always put a try/catch in these event handlers, just so I know if they throw any exceptions. I usually put a Debugger.Break(); in the catch part.
Before release, after testing, if everything seems to behave, I remove or replace these with real exception handling.
Here is something I used to drop files and/or folders full of files. In my case I was filtering for *.dwg files only and chose to include all subfolders.
fileList is an IEnumerable or similar In my case was bound to a WPF control...
var fileList = (IList)FileList.ItemsSource;
See https://stackoverflow.com/a/19954958/492 for details of that trick.
The drop Handler ...
private void FileList_OnDrop(object sender, DragEventArgs e)
{
var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
var files = dropped.ToList();
if (!files.Any())
return;
foreach (string drop in dropped)
if (Directory.Exists(drop))
files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));
foreach (string file in files)
{
if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
fileList.Add(file);
}
}
Another common gotcha is thinking you can ignore the Form DragOver (or DragEnter) events. I typically use the Form's DragOver event to set the AllowedEffect, and then a specific control's DragDrop event to handle the dropped data.
The solution of Judah Himango and Hans Passant is available in the Designer (I am currently using VS2015):
You can implement Drag&Drop in WinForms and WPF.
WinForm (Drag from app window)
You should add mousemove event:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e)
{
...
if (e.Button == MouseButtons.Left)
{
DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
}
...
}
WinForm (Drag to app window)
You should add DragDrop event:
private void YourElementControl_DragDrop(object sender, DragEventArgs e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}
Source with full code.
Note that for this to work, you also need to set the dragDropEffect within _drawEnter...
private void Form1_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("DragEnter!");
e.Effect = DragDropEffects.Copy;
}
Source: Drag and Drop not working in C# Winforms Application

How can I implement drag-and-drop to allow rearranging items in a ListView?

I would like to enable support for drag-and-drop in a ListView so that the user can rearrange the items, similar to what they can do in Windows Explorer.
Specifically, how do I enable the Drag event handler when I double-click on the ListView ?
This is what I get after double-clicking on the ListView :
private void listView1(object sender, EventArgs e)
However, I want it to be:
private void listView(object sender, DragEventArgs e)
How can I do this?
I have tried many ways, such as:
private void Form_Load(object sender, EventArgs e)
{
// Enable drag and drop for this form
// (this can also be applied to any controls)
this.AllowDrop = true;
// Add event handlers for the drag & drop functionality
this.DragEnter += new DragEventHandler(Form_DragEnter);
this.DragDrop += new DragEventHandler(Form_DragDrop);
}
But none of these seem to work.
You need to implement the DragEnter event and set the Effect property of the DragEventArgs. The DragEnter event is what allows things to be dropped into a control. After that the DragDrop event will fire when the mouse button is released.
Here is a version that will allow objects to be dropped into the a ListView:
private void Form1_Load(object sender, EventArgs e)
{
listView1.AllowDrop = true;
listView1.DragDrop += new DragEventHandler(listView1_DragDrop);
listView1.DragEnter += new DragEventHandler(listView1_DragEnter);
}
void listView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
void listView1_DragDrop(object sender, DragEventArgs e)
{
listView1.Items.Add(e.Data.ToString());
}
No doubt your sample code was taken from : http://msdn.microsoft.com/en-us/library/system.windows.forms.control.allowdrop(v=vs.71).aspx
To answer your question: There is no built in functionality for dragging and dropping items within a ListView control. Even the MSDN documentation instructs you to implement your own code-behind for the various events in order to achieve this functionality (see the ListViewInsertionMark Class)
ObjectListView (an open source wrapper around .NET WinForms ListView) provides this ability without further work (plus lots of other nice features). Have a look at the "Drag and Drop" tab of the demo.
(source: codeproject.com)

ListView, is there a simple way to allow dragging of items internally (built-in)? [duplicate]

I would like to enable support for drag-and-drop in a ListView so that the user can rearrange the items, similar to what they can do in Windows Explorer.
Specifically, how do I enable the Drag event handler when I double-click on the ListView ?
This is what I get after double-clicking on the ListView :
private void listView1(object sender, EventArgs e)
However, I want it to be:
private void listView(object sender, DragEventArgs e)
How can I do this?
I have tried many ways, such as:
private void Form_Load(object sender, EventArgs e)
{
// Enable drag and drop for this form
// (this can also be applied to any controls)
this.AllowDrop = true;
// Add event handlers for the drag & drop functionality
this.DragEnter += new DragEventHandler(Form_DragEnter);
this.DragDrop += new DragEventHandler(Form_DragDrop);
}
But none of these seem to work.
You need to implement the DragEnter event and set the Effect property of the DragEventArgs. The DragEnter event is what allows things to be dropped into a control. After that the DragDrop event will fire when the mouse button is released.
Here is a version that will allow objects to be dropped into the a ListView:
private void Form1_Load(object sender, EventArgs e)
{
listView1.AllowDrop = true;
listView1.DragDrop += new DragEventHandler(listView1_DragDrop);
listView1.DragEnter += new DragEventHandler(listView1_DragEnter);
}
void listView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
void listView1_DragDrop(object sender, DragEventArgs e)
{
listView1.Items.Add(e.Data.ToString());
}
No doubt your sample code was taken from : http://msdn.microsoft.com/en-us/library/system.windows.forms.control.allowdrop(v=vs.71).aspx
To answer your question: There is no built in functionality for dragging and dropping items within a ListView control. Even the MSDN documentation instructs you to implement your own code-behind for the various events in order to achieve this functionality (see the ListViewInsertionMark Class)
ObjectListView (an open source wrapper around .NET WinForms ListView) provides this ability without further work (plus lots of other nice features). Have a look at the "Drag and Drop" tab of the demo.
(source: codeproject.com)

Categories