Example program - drag and drop for listboxes

Drag and drop is supported between controls on a form that support object notation such as list boxes, trees and grid cells. The selection and dragging is handled entirely in the client. The program can specify using the DragStyle enumerated property whether a control will allow dragging off and or whether it can be a target of a drop When dropped onto a control whose style allows it, a Drop() event fires allowing the program perform the transfer if it deems fit. When the Drop() event handler is executing it has access to the DragSourceControl and DragSourceItem object properties defining the source control and item. Also available are DragTargetControl and DragTargetItem object properties defining the target control and item. The event handler can also check the keyboard shift state at the time of the drop by inspecting the DragKey property.

This example shows dragging between a pair of list boxes with the program enforcing a check that the drop target is suitable. There are two pair of boxes, one for fruit and one for vegetables whose .DragStyle property is set to &.DragBoth allowing them to be both a source and a target. The check in 'DoListDrag() compares the .id properties of the acceptable target and the actual target and only moves the item if they agree so that fruit cannot be moved to vegetables list and vice versa. The fifth 'Off limits' list box has its .DragStyle set to &.DragNone so it cannot accept a drop or allow its contents to be dragged. This does not require a server event and is managed entirely by the client.

Example program
// Drag and drop between list boxes
DEFFORM Form1()={.form,.form$,.Style=0x50c000c4,.Width=238,.Height=189,.Text$="Drag",.Id=1024},\
{.ok,.button$,.Style=0x50010001,.Left=186,.Top=6,.Width=50,.Height=14,.Text$="OK",.__Anchor=5,.Id=1},\
{.cancel,.button$,.Style=0x50010000,.Left=186,.Top=23,.Width=50,.Height=14,.Text$="Cancel",.__Anchor=5,.Id=2},\
{.listFruit1,.listbox$,.Style=0x50a10183,.Left=7,.Top=15,.Width=73,.Height=54,.Id=1000,.DragStyle=4},\
{.ListFruit2,.listbox$,.Style=0x50a10183,.Left=87,.Top=15,.Width=73,.Height=54,.Id=1001,.DragStyle=4},\
{.frameControl1,.groupbox$,.Style=0x50000007,.Left=1,.Top=2,.Width=165,.Height=73,.Text$="Fruit",.Id=1002},\
{.listVeg1,.listbox$,.Style=0x50a10183,.Left=7,.Top=98,.Width=73,.Height=54,.Id=1003,.DragStyle=4},\
{.ListVeg2,.listbox$,.Style=0x50a10183,.Left=86,.Top=98,.Width=73,.Height=54,.Id=1004,.DragStyle=4},\
{.frameControl2,.groupbox$,.Style=0x50000007,.Left=1,.Top=82,.Width=165,.Height=73,.Text$="Vegetables",.Id=1005},\
{.lblControl1,.static$,.Style=0x50000000,.Left=6,.Top=164,.Width=158,.Height=34,.Text$="Drag items between lists. Items may only be dragged to a list of the same type",.Id=1006,.Font=.Bold},\
{.offlimits,.listbox$,.Style=0x50a10183,.Left=179,.Top=98,.Width=52,.Height=54,.Id=1007,.DragStyle=1},\
{.frameControl3,.groupbox$,.Name$="OffLimits",.Style=0x50000007,.Left=175,.Top=82,.Width=59,.Height=73,.Text$="Off Limits",.Id=1008}
DEFEVENT Form1.Enter()
	// prime the list boxes with some fruit and veg\
	
	.listFruit1.Add("Apple")
	.listFruit1.Add("Orange")
	.listFruit1.Add("Banana")
	.listFruit1.Add("Pear")
	.listVeg1.Add("Potato")
	.listVeg1.Add("Turnip")
	.listVeg1.Add("Carrot")
	.listVeg1.Add("Cabbage")
	.offlimits.Add("Not draggable")
END EVENT
DEFEVENT Form1.listFruit1.Drop()
	'DoListDrag(OBJECT .ListFruit2)
END EVENT
DEFEVENT Form1.ListFruit2.Drop()
	'DoListDrag(OBJECT .listFruit1)
END EVENT
DEFEVENT Form1.listVeg1.Drop()
	'DoListDrag(OBJECT .ListVeg2)
END EVENT
DEFEVENT Form1.ListVeg2.Drop()
	'DoListDrag(OBJECT .listVeg1)
END EVENT
FORM END Form1
Form1.Open()
$END 
DEFSUB 'MoveListItem(OBJECT SourceItem, OBJECT DestList)
	REM Add list item to destination listbox, then remove it from the source listbox
	DestList.Add(SourceItem.Text$)
	SourceItem.Delete()
END SUB
DEFSUB 'DoListDrag(OBJECT ValidSource)
	REM Check the source control is valid before moving list item
	LOCAL DIM OBJECT SourceControl, OBJECT TargetControl
	OBJECT SourceItem = ..DragSourceItem
	OBJECT SourceControl = ..DragSourceControl
	OBJECT TargetControl = ..DragTargetControl
	IF (SourceControl.Id == ValidSource.Id)
		'MoveListItem(OBJECT SourceItem, OBJECT TargetControl)
	END IF
END SUB