MindFusion WinForms Programmer's Guide
Implementing Drag and Drop

This topic provides you with a detailed step-by-step guide on how to implement drag and drop functionality in your map.

1. Create a map. For detailed instructions how to do it, please read the "Getting Started" topic.

2. Prepare the list with the images to drag and drop.

2.1 Click on the ListView control in the Toobox panel in Visual Studio while in Design view. Place the control at the desired location in your form and size it according to your needs.

2.2. Create a folder named "Images" in your project. Add the images for the drag and drop there with the "Add existing item" command.

2.3 Initialize a strongly typed List<image> that will hold all the images. Write the following line in the code-behind class of the form that holds the MapView control and the ListView with the images:

C#  Copy Code

List<Image> images = new List<Image>();

VB.NET  Copy Code

Dim images As New List(Of Image)()

2.4  Load the images from your directory and add them as ListViewItem-s in your ListView control:

C#  Copy Code

// load images
var imgFolder = new DirectoryInfo("Images");

//create a list that will hold the images
var imgList = lvImages.LargeImageList = new ImageList();

//set the image size
imgList.ImageSize = new Size(32, 32);

//loop through all loaded image files
foreach (var imgFile in imgFolder.GetFiles())

     //add each image to the ImageList
     var image = Image.FromFile(imgFile.FullName);
     images.Add(image);

     //create a ListViewItem from each image
     var item = new ListViewItem(
     Path.GetFileNameWithoutExtension(imgFile.Name),
     imgList.Images.Count);

     //add the Image to the image list
     imgList.Images.Add(image);
     
     //add the ListBoxItem to the ListBox
     lvImages.Items.Add(item);
}

//set a proper view for the ListView control
lvImages.View = View.Tile;

//create a DecorationLayer over the MapView control
//that will draw the images
decorationLayer = new DecorationLayer(map.BoundingBox);
mapView.Layers.Add(decorationLayer);
mapView.Focus();

VB.NET  Copy Code

' load images
Dim imgFolder = New DirectoryInfo("Images")

'create a list that will hold the images
Dim imgList = InlineAssignHelper(lvImages.LargeImageList, New ImageList())

'set the image size
imgList.ImageSize = New Size(32, 32)

'loop through all loaded image files
For Each imgFile As var In imgFolder.GetFiles()
   'add each image to the ImageList
    Dim image__1 = Image.FromFile(imgFile.FullName)
    images.Add(image__1)

    'create a ListViewItem from each image
    Dim item = New ListViewItem(Path.GetFileNameWithoutExtension(imgFile.Name), imgList.Images.Count)

    'add the Image to the image list
    imgList.Images.Add(image__1)

    'add the ListBoxItem to the ListBox
    lvImages.Items.Add(item)
Next

'set a proper view for the ListView control
lvImages.View = View.Tile

'create a DecorationLayer over the MapView control
'that will draw the images
decorationLayer = New DecorationLayer(map.BoundingBox)
mapView.Layers.Add(decorationLayer)
mapView.Focus()

3. Add event handler for the ItemDrag event of the ListView control.

C#  Copy Code

this.lvImages.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.lvImages_ItemDrag);

VB.NET  Copy Code

Me.lvImages.ItemDrag += New System.Windows.Forms.ItemDragEventHandler(Me.lvImages_ItemDrag)

3.1 Provide the event with data about the index of the image being dragged.

C#  Copy Code

private void lvImages_ItemDrag(object sender, ItemDragEventArgs e)
{
    DoDragDrop(lvImages.SelectedIndices[0], DragDropEffects.Copy);
}

VB.NET  Copy Code

Private Sub lvImages_ItemDrag(sender As Object, e As ItemDragEventArgs)
   DoDragDrop(lvImages.SelectedIndices(0), DragDropEffects.Copy)
End Sub

4. Handle the DragOver event of the MapView.

C#  Copy Code

this.mapView.DragOver += new System.Windows.Forms.DragEventHandler(this.mapView_DragOver);

VB.NET  Copy Code

Me.mapView.DragOver += New System.Windows.Forms.DragEventHandler(Me.mapView_DragOver)

4.1 Get the location where the image is about to be dropped and if that's a valid location - copy there the file:

C#  Copy Code

private void mapView_DragOver(object sender, DragEventArgs e)
{
     //get the client coordinates of the specified screen point
     var clientPoint = mapView.PointToClient(new Point(e.X, e.Y));

      //get the map coordinates of the specified client point
      var geoLocation = mapView.ClientToMap(clientPoint);

      //get the region where the item will be dropped
      var province = mapView.BaseMap.HitTest(geoLocation);

      //copy the dragged image into the specified province
      e.Effect = province != null ? DragDropEffects.Copy : DragDropEffects.None;
}

VB.NET  Copy Code

Private Sub mapView_DragOver(sender As Object, e As DragEventArgs)
     'get the client coordinates of the specified screen point
     Dim clientPoint = mapView.PointToClient(New Point(e.X, e.Y))

     'get the map coordinates of the specified client point
     Dim geoLocation = mapView.ClientToMap(clientPoint)

     'get the region where the item will be dropped
     Dim province = mapView.BaseMap.HitTest(geoLocation)

     'copy the dragged image into the specified province
     e.Effect = If(province IsNot Nothing, DragDropEffects.Copy, DragDropEffects.None)
End Sub

5. Handle the DragDrop event of the MapView.

C#  Copy Code

this.mapView.DragDrop += new System.Windows.Forms.DragEventHandler(this.mapView_DragDrop);

VB.NET  Copy Code

Me.mapView.DragDrop += New System.Windows.Forms.DragEventHandler(Me.mapView_DragDrop)

5.1 Create a DecorationImage together with a label and place it at the location where it has been dropped.

C#  Copy Code

private void mapView_DragDrop(object sender, DragEventArgs e)
{
   //get the client coordinate of the specified screen coordinate
   var clientPoint = mapView.PointToClient(new Point(e.X, e.Y));

   //get the map coordinate of the specified client coordinate
   var geoLocation = mapView.ClientToMap(clientPoint);

   //check if the drop location is a valid region
   var region = mapView.BaseMap.HitTest(geoLocation);

   //if this is valid region the image must be copied
   e.Effect = region != null ? DragDropEffects.Copy : DragDropEffects.None;

   if (region != null)
   {
      //get the index of the image
      int index = (int)e.Data.GetData(typeof(Int32));

      //create a DecorationImage to add to the DecorationLayer
      var decoration = new DecorationImage(
      images[index], geoLocation.Y, geoLocation.X);

      //set the label
      decoration.Label = lvImages.Items[index].Text +
       " in " + region.DatabaseRow["NAME_1"];

      //add the image
      decorationLayer.Decorations.Add(decoration);

      //repaint the map
      mapView.Invalidate();
   }
}

VB.NET  Copy Code

Private Sub mapView_DragDrop(sender As Object, e As DragEventArgs)
    'get the client coordinate of the specified screen coordinate
     Dim clientPoint = mapView.PointToClient(New Point(e.X, e.Y))

    'get the map coordinate of the specified client coordinate
     Dim geoLocation = mapView.ClientToMap(clientPoint)

    'check if the drop location is a valid region
     Dim region = mapView.BaseMap.HitTest(geoLocation)

     'if this is valid region the image must be copied
     e.Effect = If(region IsNot Nothing, DragDropEffects.Copy, DragDropEffects.None)

     If region IsNot Nothing Then
        'get the index of the image
         Dim index As Integer = CInt(e.Data.GetData(GetType(Int32)))

        'create a DecorationImage to add to the DecorationLayer
        Dim decoration = New DecorationImage(images(index), geoLocation.Y, geoLocation.X)

        'set the label
        decoration.Label = lvImages.Items(index).Text + " in " + region.DatabaseRow("NAME_1")

        'add the image
        decorationLayer.Decorations.Add(decoration)

        'repaint the map
        mapView.Invalidate()
  End If
End Sub

6. By now you must have working drag and drop functionality in your map from the kind shown below: