/\ 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).
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:
- x becomes i. I just prefer my loop counters to be i.
- 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:
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 /\