Supporting drag and drop

Controls support drag & drop between each other and to or from destinations outside of Xojo.

These are the type of drops that are supported:

  • Files

  • Pictures

  • Raw Data

  • Text

To allow one of these types of drops onto a control, in the Opening event for the control call the appropriate "Accept" method. The methods are: AcceptFileDrop, AcceptPictureDrop, AcceptRawDataDrop and AcceptTextDrop. When a control is set to accept a drop it will then receive the various drag events: DragEnter, DragExit, DragOver and DropObject. In most cases you are interested in the DropObject event which passes in a DragItem containing the details of the item being dropped.

Text Fields and Text Areas support textual drag and drop automatically.

Drag text onto a label

The idea here is that you will let the user select some text in a Text Field and drag that text onto a Label where the label will display the dragged text. Here are the steps:

  1. Add a Label and a TextField to a Window layout.

  2. In the Opening event handler for the Label, add this code to allow text drags:

Me.AcceptTextDrop
  1. Add the DropObject event handler to the Label and add this code to display the text that was dropped on it:

If obj.TextAvailable Then
  Me.Text = obj.Text
End If

Now you can run the project, type some text in the text field, select it and then drag and drop it onto the label to see the label's text get replaced with your selected text.

Drag label text onto a text field

Suppose you want to do the opposite and allow the user to drag a label and have its text be added to a text field. Starting with the project you created for Drag Text Onto a Label you can add some additional code to allow the label to be dragged. 1. Go back to the Label you added above and add the MouseDown and MouseDrag event handlers.

  1. Add this code to MouseDown:

Return True ' Allow subsequent mouse events
  1. Now add this code to MouseDrag which creates a DragItem, populates it with the text from the Label and then starts the drag:

Var dragLabel As DragItem
dragLabel = New DragItem(Self, Me.Left, Me.Top, Me.Width, Me.Height)
dragLabel.Text = Me.Text
dragLabel.Drag
  1. Add the Opening event handler to the Text Field and add this code to tell it to accept text drops:

Me.AcceptTextDrop
  1. Add the DropObject event handler to the textfield with this code to get the text from the drop and display it:

If obj.TextAvailable Then
  Me.Text = obj.Text
End If

Run the project and drag the Label onto the TextField to see the Label text replace what is in the TextField.

Drag a file onto a ListBox

To get a little more advanced, suppose you want to allow the user to drag files from the Finder (or File Explorer, etc.) and add the filename to a DesktopListBox</api/user_interface/desktop/desktoplistbox. Here are the steps.

  1. Since you are going to accept files the first thing to add is a File Type Group from the Insert menu or toolbar.

  2. In the File Type Group, select the first toolbar button (Add Common File Type) and from the dropdown choose "special/any".

  3. Now go to Window1 and add a ListBox to it.

  4. Add the Opening event handler to the ListBox with this code to tell it to accept file drops for any file:

Me.AcceptFileDrop(FileTypeGroup1.Any)
  1. Lastly, add the DropObject event handler to the ListBox with this code to grab the filename from the dropped file and add it as a row to the ListBox:

If obj.FolderItemAvailable Then
  Me.AddRow(obj.FolderItem.Name)
End If

Run the project and drag a file from the Finder (or File Explorer, etc.) onto the ListBox where its name should get added to the list.

Drag a picture onto a Canvas

A picture can come from a variety of sources. It could actually be a file so accepting a picture would work similarily to accepting a file as shown above. But a picture can also sometimes come directly from another app such as a web browser or drawing app. This is how you can accept picture drags from other apps to display in a Canvas.

  1. In order to accept drags of files that are pictures you need to create a File Type Set.

  2. Add two Common File Types, one for image/png and one for image/jpeg.

  3. Now add a Canvas to Window1.

  4. In the Opening event handler for the Canvas, add this code to accept drops for Pictures and the PNG and JPG files that you added to the File Type Set:

' Accept pictures from other apps such as some web browsers
Me.AcceptPictureDrop

' Accept pictures dragged from files
Me.AcceptFileDrop("image/png")
Me.AcceptFileDrop("image/jpeg")
  1. Add a property to the window which will store the picture that gets dropped onto the window so that the Canvas can draw it:

DropPic As Picture
  1. Add the Paint even to the Canvas. This code draws the picture when it is available:

If DropPic Is Nil Then Return
g.DrawPicture(DropPic, 0, 0, g.Width, g.Height, 0, 0, DropPic.Width, DropPic.Height)
  1. Add the DropObject event to the Canvas with this code which determines the type of drop, gets the Picture and then tells the Canvas to draw it:

If obj.PictureAvailable Then
  DropPic = obj.Picture
ElseIf obj.FolderItemAvailable Then
  DropPic = Picture.Open(obj.FolderItem)
End If

Me.Refresh ' Draw the picture

You can now run the project and drag a picture file onto the Canvas area. Some browsers (such as Safari) also let you drag a picture from the browser onto the Canvas area.

Drag rows from a ListBox to a text field

You can drag rows within a single ListBox for reordering by turning on the AllowRowReordering property. But if you want to allow individual rows to be dragged out of a ListBox you have to do a bit more coding. For this example you will allow a ListBox row to be dragged onto a TextField.

  1. Add a ListBox to a Window and turn its AllowRowDragging property to ON from the Inspector.

  2. Add some initial data to the ListBox using the InitialValue property in the Inspector.

  3. Add the DragRow event handler to the ListBox with this code to make a DragItem using the text from the row:

drag.Text = Me.CellTextAt(row, 0)
Return True ' to allow the drag
  1. Now add a TextField and in its Opening event handler tell it to accept text drops:

Me.AcceptTextDrop
  1. Add the DropObject event handler to the TextField with this code to display the text from the drop:

If obj.TextAvailable Then
  Me.Text = obj.Text
End If

Now you can run the project and drag a row from the ListBox onto the Text Field where the text will be displayed.

See also

DragItem class