Extended drag and drop listbox example

/\ Back to REALbasic /\

By Peter F. Whyte, 5 Feb 2009

Original article: Jay Jennings, RB Nation, REALbasic Listbox – Drag-and-Drop (29 Jan 2008)

I wanted to take Jay’s tutorial a little further, just to see if I could, and to see if I really understood what was going on. You’ll need to watch his video first and continue here for the extras. This is what the starting point looks like (in Windows XP).

Basic Drag and Drop Listboxes

Basic Drag and Drop Listboxes

Step 1: Move dragged rows

The first thing I wanted to do was to remove the items dragged from one list to the other, that is, to move the items instead of copying them.

Source for Listbox1.DragRow

dim i as Integer
dim oneRow as String
oneRow = me.List(row) // only takes first cell
// build tab-delimited string of all cells in row
for i = 1 to me.ColumnCount
  oneRow=oneRow + chr(9) + me.Cell(row,i)
next
drag.Text = oneRow
me.RemoveRow(row) // remove row from original list
return true

There are two changes to Jay’s code here:

  1. x becomes i. I just prefer my loop counters to be i.
  2. I’ve added a line to remove the row that is being dragged to the other listbox: me.RemoveRow(row)

Source for Listbox2.DropObject

  dim i, numCols as Integer

  // add value to first cell in row
  me.AddRow(nthfield(obj.Text,chr(9),1))

  // determine how many columns exist
  numCols=CountFields(obj.Text,chr(9))

  // add values to remaining cells in row
  for i = 2 to numCols
    me.Cell(me.LastIndex,i-1) = NthField(obj.Text,chr(9),i)
  next

No real changes here, just the x to i to suit my preferences.

Source for Listbox2.Open

me.AcceptTextDrop

And just to prove that it works:

Rows dragged to bottom listbox

Rows dragged to bottom listbox

Step 2: Two-way drag and drop

The next thing I wanted to do was enable drag and drop both ways.

This very easy. Just copy the  code from each listbox to the other, so both listboxes will now have code in their DragRow, DropObject and Open actions.

Step 3: Refactor code to methods

The code in DragRow and DropObject is identical for each listbox, so we could move each of them into a method, and let each listbox call the appropriate method.

Refactor DropObject

Copy the code from one listbox’s DropObject action and create a Method (click on Add Method).

Paste the code into the code window.

Name the method DropListBoxRow.

We need two parameters for this method:

lbox as Listbox, drag as DragItem

The method needs to know which listbox to operate on, so lbox will represent the calling listbox, so change all the code references to me to lbox.

The original DropObject action used a DragItem object, so we need to pass this object to our new method, so that it can get at the data that has been dragged to the listbox. (There was an action parameter in the original action, but as we have not used it in our code so far we do not need to pass it across.)

Source for DropListboxRow:

  dim i, numCols as Integer

  // add value to first cell in row
  lbox.AddRow(nthfield(drag.Text,chr(9),1))

  // determine how many columns exist
  numCols=CountFields(drag.Text,chr(9))

  // add values to remaining cells in row
  for i = 2 to numCols
    lbox.Cell(lbox.LastIndex,i-1) = NthField(drag.Text,chr(9),i)
  next

Finally, replace the action with a call to our new method.

Source for Listbox.DropRow:

DropListboxRow(me,obj)

And test that the program still works. If not, check back and see if there are any errors that passed the syntax check.

Once DropListBoxRow is working for one listbox, replace the action in the other with the new call, and check to see that it works.

Refactor DragObject

Copy the code from one listbox’s DragObject action and create a Method (click on Add Method).

Paste the code into the code window, but remove the return statement. This needs to be retained in the listbox action.

Name the method DragListBoxRow.

We need three parameters for this method:

lbox As Listbox, drag As DragItem, row As Integer

The method needs to know which listbox to operate on, so lbox will represent the calling listbox, so change all the code references to Me to lbox.

The original DragObject action used a DragItem object, so we need to pass this object to our new method, so that it can get at the data that has been dragged to the listbox.

The original DragObject also used a row parameter, which we also need passed to our new method.

Source for DragListboxRow:

  dim i as Integer
  dim oneRow as String

  oneRow = lbox.List(row) // only takes first cell
  // build tab-delimited string of all cells in row
  for i = 1 to lbox.ColumnCount
    oneRow=oneRow + chr(9) + lbox.Cell(row,i)
  next

  drag.Text = oneRow
  lbox.RemoveRow(row) // remove row from original list

Finally, replace the action with a call to our new method, but retain the return statement.

Source for Listbox.DragRow:

  DragListboxRow(me,drag,row)
  return true

And test that the program still works. If not, check back and see if there are any errors that passed the syntax check.

Once DropListBoxRow is working for one listbox, replace the action in the other with the new call, and check to see that it works.

Step 4: Permit drag and drop sort within each listbox

Once you have dragged various rows around between the listboxes they can be a little mixed up. It would be nice if the order of items in each listbox could be tidied up. You could sort them, but if manual reordering is required, then all you have to do is tick to box for the property EnableDragReorder in the control’s property sheet.

Ω

/\ Back to REALbasic /\

Leave a Reply

Your email address will not be published. Required fields are marked *