Move Items Between List Boxes

File: SAMPLES\SOLUTION\CONTROLS\LISTS\LMOVER.SCX

This sample demonstrates moving items from one list box to another. A user can double-click one item to move it, or select one or more items and drag them, or use the appropriate command buttons to move the items between the lists.

The two list boxes and four associated command buttons are saved as a class: MoverLists in SAMPLES.VCX. The base class of MoverLists is CONTAINER. To be able to add and remove items from lists, the RowSourceType of the lists must be set to 0 - None. If you want to fill the list box with array elements or values from a table, you can use code like the following:

*array
FOR i = 1 to ALEN(myarray)
	List.AddItem(myarray[i])
ENDFOR

*table
SCAN
	List.AddItem(table.field)
ENDSCAN

To Move Items by Double-Clicking

The following code is associated with the DblClick event of the left list box (lstSource). Similar code is associated with the DblClick event of the right list box (lstSelected).

THIS.Parent.lstSelected.AddItem(THIS.List(THIS.ListIndex))
This.RemoveItem(THIS.ListIndex)
THIS.Parent.Refresh

"THIS" refers to lstSource. "THIS.Parent" refers to the moverlists class, the container of the lists.

To Move All Items from One List to Another

The following code is associated with the Click event of cmdAddAll:

  DO WHILE THIS.PARENT.lstSource.ListCount > 0
    THIS.PARENT.lstSelected.AddItem;
  		(THIS.PARENT.lstSource.List(1))
	THIS.PARENT.lstSource.RemoveItem(1)
  ENDDO
  THIS.PARENT.Refresh

To Move Selected Items from One List to Another

If you remove an item from a list box, the ListCount property of the list box is decremented, as is the ListIndex of all the subsequent items in the list. To move multiply-selected items, you need to use a DO WHILE loop. The following code is associated with the Click event of cmdAdd:

nCnt = 1
DO WHILE nCnt <= THIS.PARENT.lstSource.ListCount
	IF THIS.PARENT.lstSource.Selected(nCnt)
		THIS.PARENT.lstSelected.AddItem;
			(THIS.PARENT.lstSource.List(nCnt))
		THIS.PARENT.lstSource.RemoveItem(nCnt)
	ELSE
		nCnt = nCnt + 1
	ENDIF
ENDDO
THIS.PARENT.Refresh

To Drag-and-Drop Items from One List to Another

Implementing drag-and-drop between the list boxes involves code associated with the MouseDown, MouseMove, DragOver, and DragDrop events. Three user-defined properties (DragThreshold, MouseX, and MouseY) extend the usability of the class.

The MouseDown code stores the X and Y coordinates of the mouse pointer to class properties.

*MouseDown
Parameters nButton, nShift, nXCoord, nYCoord
THIS.PARENT.MouseX = nXCoord
THIS.PARENT.MouseY = nYCoord

The MouseMove code makes sure the left mouse button in pressed before initiating the drag procedure. In addition, to guard against accidental dragging, this code checks to make sure that the user has moved the mouse a distance greater than a set threshold (8 pixels by default).

*MouseMove
Parameters nButton, nShift, nXCoord, nYCoord
IF nButton = 1 && Left Mouse
	IF ABS(nXCoord - THIS.PARENT.MouseX) > ;
		THIS.Parent.DragThreshold OR ;
			ABS(nYCoord - THIS.PARENT.MouseY) > ;
			THIS.Parent.DragThreshold
		THIS.Drag
	ENDIF
ENDIF

The DragOver code changes the DragIcon of the source when the mouse pointer enters and leaves the list box “air space.”

*DragOver
Parameters oSource, nXCoord, nYCoord, nState
DO CASE
	CASE nState = 0 && Enter
		oSource.DragIcon = THIS.Parent.CanDropIcon
	CASE nState = 1 && Leave
		oSource.DragIcon = THIS.Parent.NoDropIcon
ENDCASE

The DragDrop code makes sure that the source of the drag is not the same as the target of the drag and calls the method associated with the Click event of the cmdAdd command button (in the case of lstSelected) or cmdRemove (in the case of lstSource).

*DragDrop
Parameters oSource, nXCoord, nYCoord
IF oSource.Name != THIS.Name
	THIS.PARENT.cmdAdd.Click
ENDIF