|
|
#1 |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Drag & Drop in Windows Forms
VB version here.
I'm sure others have posted about this topic before but I'm sure another won't hurt. I'll post various examples of drag & drop within the same control, between controls and between applications. If you're interested in performing drag & drop operations in WinForms then I suggest that you read this and this at least. I'll start with moving items between two ListBoxes, which is relatively simple. 1. Create a new WinForms application project. 2. Add two ListBoxes to the form. 3. Replace the existing form code with the following: Code:
public Form1()
{
InitializeComponent();
// Hook up the form event handler.
this.Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object sender, EventArgs e)
{
// Allow data to be dropped on both ListBoxes.
this.listBox1.AllowDrop = true;
this.listBox2.AllowDrop = true;
// Populate the ListBoxes.
this.listBox1.Items.AddRange(new string[] {"List 1, Item 1",
"List 1, Item 2",
"List 1, Item 3",
"List 1, Item 4",
"List 1, Item 5"});
this.listBox2.Items.AddRange(new string[] {"List 2, Item 1",
"List 2, Item 2",
"List 2, Item 3",
"List 2, Item 4",
"List 2, Item 5"});
// Hook up the ListBox event handlers.
this.listBox1.MouseDown += new MouseEventHandler(ListBox_MouseDown);
this.listBox2.MouseDown += new MouseEventHandler(ListBox_MouseDown);
this.listBox1.DragEnter += new DragEventHandler(ListBox_DragEnter);
this.listBox2.DragEnter += new DragEventHandler(ListBox_DragEnter);
this.listBox1.DragDrop += new DragEventHandler(ListBox_DragDrop);
this.listBox2.DragDrop += new DragEventHandler(ListBox_DragDrop);
}
void ListBox_MouseDown(object sender, MouseEventArgs e)
{
ListBox source = (ListBox)sender;
for (int index = 0; index < source.Items.Count; index++)
{
// Test whether the mouse location is within an item
if (source.GetItemRectangle(index).Contains(e.Location))
{
// The mouse was depressed on an item so allow a move operation.
source.DoDragDrop(source, DragDropEffects.Move);
break;
}
}
}
void ListBox_DragEnter(object sender, DragEventArgs e)
{
ListBox source = (ListBox)sender;
if (e.Data.GetDataPresent("System.Windows.Forms.ListBox", false) &&
e.Data.GetData("System.Windows.Forms.ListBox", false) != source)
{
// The data being dragged is a ListBox but not the one that was just entered.
e.Effect = DragDropEffects.Move;
}
}
void ListBox_DragDrop(object sender, DragEventArgs e)
{
ListBox source = (ListBox)sender;
if (e.Data.GetDataPresent("System.Windows.Forms.ListBox", false))
{
// Get the ListBox that the data was dragged from.
ListBox data = (ListBox)e.Data.GetData("System.Windows.Forms.ListBox", false);
// Make sure we aren't trying to drag from and drop to the same control.
if (data != source)
{
// Get the item that was dragged.
object item = data.SelectedItem;
// Remove the item from its original location.
data.Items.Remove(item);
// Get the current mouse location relative to the control being dropped on.
Point location = source.PointToClient(new Point(e.X, e.Y));
int dropIndex = -1;
// Find the item over which the mouse was released.
for (int index = 0; index < source.Items.Count; index++)
{
if (source.GetItemRectangle(index).Contains(location))
{
dropIndex = index;
break;
}
}
if (dropIndex == -1)
{
// The mouse was not released over an item so add the new item to the end.
source.Items.Add(item);
}
else
{
// Insert the new item above the item it was dropped on.
source.Items.Insert(dropIndex, item);
}
}
}
}
I'll refine this example and add more over time. If there's anything you specifically want to see then post a request and I'll see if I can get to it.
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET Last edited by jmcilhinney; Nov 15th, 2008 at 03:47 AM. |
|
|
|
|
|
#2 |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Dragging Files From Windows Explorer
This example demonstrates dragging one or more files from Windows Explorer, or some other application that supports dragging files, into a ListView.
1. Create a new WinForms project. 2. Add a ListView and an ImageList to the form. 3. Replace the contents of the form with the following code: Code:
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
// Initialise the ListView.
this.listView1.AllowDrop = true;
this.listView1.Columns.Add("File name");
this.listView1.Dock = DockStyle.Fill;
this.listView1.SmallImageList = this.imageList1;
this.listView1.View = View.Details;
this.listView1.DragEnter += new DragEventHandler(listView1_DragEnter);
this.listView1.DragDrop += new DragEventHandler(listView1_DragDrop);
}
void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("FileDrop") &&
(e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
{
// A file list is being dragged and it can be copied so provide feedback to the user.
e.Effect = DragDropEffects.Copy;
}
}
void listView1_DragDrop(object sender, DragEventArgs e)
{
// The data can only be dropped if it is a file list and it can be copied.
if (e.Data.GetDataPresent("FileDrop") &&
(e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
{
// Get the data.
string[] filePaths = (string[])e.Data.GetData("FileDrop");
ListViewItem[] items = new ListViewItem[filePaths.Length];
string filePath;
// For each file in the list, create an item, complete with icon.
for (int index = 0; index < filePaths.Length; index++)
{
filePath = filePaths[index];
if (!this.imageList1.Images.Keys.Contains(filePath))
{
// This is the first time this file has been added so add its icon too.
this.imageList1.Images.Add(filePath,
Icon.ExtractAssociatedIcon(filePath));
}
items[index] = new ListViewItem(filePath, filePath);
}
// Add the items to the ListView.
this.listView1.Items.AddRange(items);
}
}
5. Select one or more files in Windows Explorer and drag them onto your form. Tada! Note that, as before, I've done some setup of design time elements that you'd normally do in the designer. It was easier to do it in code than to explain though, for the purpose of this example.
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET Last edited by jmcilhinney; Nov 12th, 2008 at 07:41 PM. |
|
|
|
|
|
#3 |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Determining How to Retrieve the Data
I'm going to use that last example as a basis for showing you build up drag & drop code. I can hear people now saying "But how would I know to use the FileDrop format and how would I know that it returns a String array". Well, I'm going to show you how you work that out.
First up, you have to make sure that your control is a drop target, so set its AllowDrop property to True. Next you need to test what formats the data being dragged is available in. To do that you use the GetFormats method. GetFormats returns a String array, so you can loop through it to see what formats you can get the data in: CSharp Code:
You now need to determine what .NET object will be created if you get the data in each of those formats and then decide which of those is most useful to you. To do that, you first need to get the data in each of those formats and then test it's type: CSharp Code:
vb.net Code:
That's basically how you should approach all drag & drop operations.
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET |
|
|
|
|
|
#4 |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Reordering Items in a ListBox
1. Create a new Windows Forms project.
2. Add a ListBox to the form. 3. Replace the existing code of the form with the following: Code:
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object sender, EventArgs e)
{
// Initialise the ListBox.
this.listBox1.AllowDrop = true;
this.listBox1.Items.AddRange(new string[] {"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5"});
this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
this.listBox1.DragEnter += new DragEventHandler(listBox1_DragEnter);
this.listBox1.DragOver += new DragEventHandler(listBox1_DragEnter);
this.listBox1.DragDrop += new DragEventHandler(listBox1_DragDrop);
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
// Test whether the mouse is over an item.
if (this.GetItemIndexAtPoint(e.Location) != -1)
{
// The mouse is over an item so start dragging.
this.listBox1.DoDragDrop(this.listBox1, DragDropEffects.Move);
}
}
private void listBox1_DragEnter(object sender, DragEventArgs e)
{
// Test whether the data being dragged is the ListBox itself.
if (e.Data.GetDataPresent("System.Windows.Forms.ListBox") &&
e.Data.GetData("System.Windows.Forms.ListBox") == this.listBox1)
{
// Get the location of the mouse relative to the ListBox.
Point mouseLocation = this.listBox1.PointToClient(new Point(e.X, e.Y));
// Force the location to be within the horizontal bounds of the ListBox.
if (mouseLocation.X < 0)
{
mouseLocation.X = 0;
}
else if (mouseLocation.X > this.listBox1.Width)
{
mouseLocation.X = this.listBox1.Width;
}
// Force the location to be within the vertical bounds of the ListBox.
if (mouseLocation.Y < 0)
{
mouseLocation.Y = 0;
}
else if (mouseLocation.Y > this.listBox1.Height)
{
mouseLocation.Y = this.listBox1.Height;
}
if (this.GetItemIndexAtPoint(mouseLocation) == this.listBox1.SelectedIndex)
{
// Don't allow the selected item to be dropped on itself.
e.Effect = DragDropEffects.None;
}
else
{
// Allow the selected item to be moved.
e.Effect = DragDropEffects.Move;
}
}
}
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
// Test whether the data being dragged is the ListBox itself and the selected item can be moved.
if (e.AllowedEffect == DragDropEffects.Move &&
e.Data.GetDataPresent("System.Windows.Forms.ListBox") &&
e.Data.GetData("System.Windows.Forms.ListBox") == this.listBox1)
{
int selectedIndex = this.listBox1.SelectedIndex;
// Get the index of the item being dropped on.
int dropIndex = this.GetItemIndexAtPoint(this.listBox1.PointToClient(new Point(e.X, e.Y)));
// If the item being dropped on is below the selected item, the index of the
// item being dropped on will decrement once the selected item is removed.
if (dropIndex > selectedIndex)
{
dropIndex -= 1;
}
object selectedItem = this.listBox1.SelectedItem;
this.listBox1.Items.Remove(selectedItem);
if (dropIndex == -1)
{
// The item was dropped after the last item so add it at the end of the list.
this.listBox1.Items.Add(selectedItem);
}
else
{
// Insert the item above the item it was dropped on.
this.listBox1.Items.Insert(dropIndex, selectedItem);
}
this.listBox1.SelectedItem = selectedItem;
}
}
private int GetItemIndexAtPoint(Point location)
{
int itemIndex = -1;
for (int index = 0; index < this.listBox1.Items.Count; index++)
{
// Test whether the location is within an item.
if (this.listBox1.GetItemRectangle(index).Contains(location))
{
itemIndex = index;
break;
}
}
return itemIndex;
}
When you drop an item it will be moved to the position above the item you dropped it on. If you drop it after the last item it will be moved to the end of the list.
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET |
|
|
|
|
|
#5 | |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Dropping Image Files on a PictureBox
Quote:
Now, this first code example will allow you to drop multiple files on the PictureBox but it simply ignores all but the first file: vb.net Code:
In the DragDrop event handler we don't need to test the data again because we know that, if the effect is Copy then the data must have passed the test in the DragEnter event handler. That means we simply get the first file path and load it into the PictureBox. It should be noted that the IsImageFile method is using a brute force approach to determine whether the file is an image or not. It simply creates an Image object and handles the exception that's thrown if it fails. This is not ideal but there really isn't another way (that I'm aware of) to perform this test. For clarity, here's the DragEnter event handler rewritten with the code extended out a bit: vb.net Code:
vb.net Code:
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET |
|
|
|
|
|
|
#6 |
|
New Member
Join Date: Oct 08
Posts: 14
![]() |
Re: Drag & Drop in Windows Forms
hey jmcilhinney very nice projects!!!can you do me a favour??i keep trying to make the program "Reordering Items in a ListBox" to vb 2005 but it seems that i m failing every time...can you do it for me or at least tell me what do i need to change???thanks in advance...
|
|
|
|
|
|
#7 |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: Drag & Drop in Windows Forms
Did you connect the event handlers after adding the code? In VB you have a Handles clause so event handlers get wired up automatically. In C# you have to do it manually by selecting the appropriate method from the drop-down list in the Properties window, after clicking the Events button.
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET |
|
|
|
|
|
#8 |
|
New Member
Join Date: Oct 08
Posts: 14
![]() |
Re: Drag & Drop in Windows Forms
it gives me errors at these points
Me.Load += New EventHandler(Form1_Load) and Me.ListBox1.MouseDown += New MouseEventHandler(listBox1_MouseDown) Me.ListBox1.DragEnter += New DragEventHandler(listBox1_DragEnter) Me.ListBox1.DragOver += New DragEventHandler(listBox1_DragEnter) Me.ListBox1.DragDrop += New DragEventHandler(listBox1_DragDrop) the error is Public Event Load(sender As Object, e As System.EventArgs)' is an event and cannot be called directly. Use a 'RaiseEvent' statement to raise an event. i tried using AddHandler Me.Load, AddressOf Form1_Load but it won't work thanks for the help...sorry for my english |
|
|
|
|
|
#9 | |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 60,536
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: Drag & Drop in Windows Forms
Quote:
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET |
|
|
|
|
|
|
#10 |
|
Web developer
Join Date: Dec 01
Location: Adelaide, Australia
Posts: 4,539
![]() ![]() |
Re: Drag & Drop in Windows Forms
Thanks! I was wondering how I could do this in C# after created an old example in Visual Basic 6.0 years ago.
__________________
My websites My code projects: Backup mysql database 5.3.0 Visual Basic 6.0 Office Outlook mail retrieval Visual Basic 6.0 Client/Server example Visual Basic 6.0 Get number of file in a directory Visual Basic 6.0 Get and Save Ascii Values on keyboard Visual Basic 6.0 Get control name Visual Basic 6.0 Copy application to a different directory Flash Action Script 3 - XML button label VB6.0 - Basic Flash Player Please rate my post if you find it helpful! ![]() I am yet to see a forum without a quote button! If there is I should join it. |
|
|
|
![]() |
|
||||||
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|