Multi-row select for Grid control
From DataFlex Wiki
Jump to navigationJump to search
Functionality
This code demonstrates how to select multiple rows in a Grid. The code will work no matter how many columns. The object of this code is to allow the user to use the SHIFT+RCLICK or CTRL+RCLICK key to select multiple rows just like a spreadsheet program.
Example
Paste this code into a test view to test it and see how it works. Once compiled, you will see a narrow column on the left that acts as a margin. Clicking this gray cell will highlight the row. Using SHIFT or CTRL and clicking another gray cell will select multiple rows.
Object oGrid1 is a Grid
Set Location to 7 26
Set Size to 116 207
Set Line_Width to 4 0
Set Form_Width 0 to 8
Set Header_Label 0 to ""
Set Form_Width 1 to 60
Set Header_Label 1 to "Column 1"
Set Form_Width 2 to 60
Set Header_Label 2 to "Column 2"
Set Form_Width 3 to 60
Set Header_Label 3 to "Column 3"
// BEGIN MULTI-SELECT CODE
// DO NOT MODIFY
Set Select_Mode to Multi_Select
Property Integer[] paiSelected
Property Integer piLastSelected 0
Procedure Select_Toggling Integer iItem Integer iState
Integer iCurrent iCol iLast iCount iFrom iTo iRet iUpdate
Integer[] aiSelected aiEmpty
//
Get Dynamic_Update_State to iUpdate
Set Dynamic_Update_State to False
// Get base item
Move (Current_Item(Self)) to iCurrent
Move (Mod(iCurrent , Line_Size(Self))) to iCol
Subtract iCol from iCurrent
// get list of selected items
Move (paiSelected(Self)) to aiSelected
Move (SizeOfArray(aiSelected)) to iCount
//
Move (GetAsyncKeyState(VK_CONTROL)) to iRet
If (iRet<>0) Begin
If (iState) Begin
// add selected item
Move iCurrent to aiSelected[iCount]
// Update last selected with this item
Set piLastSelected to iCurrent
// Select Current row
For iCol from 0 to (Line_Size(Self)-1)
Forward Send Select_Toggling (iCurrent+iCol) iState
Loop
End
Else Begin
// remove selected item
For iItem from 0 to (iCount-1)
Move aiSelected[iItem] to iLast
If (iLast=iCurrent) Move -1 to aiSelected[iItem]
Loop
// Update last selected with this item
Set piLastSelected to -1
End
End
Else Begin
// If shift is used, we will ignore
// the state of the clicked row
// unselect everything
For iItem from 0 to (iCount-1)
Move aiSelected[iItem] to iLast
For iCol from 0 to (Line_Size(Self)-1)
Forward Send Select_Toggling (iLast+iCol) False
Loop
Loop
Move aiEmpty to aiSelected
//
Move (GetAsyncKeyState(VK_SHIFT)) to iRet
If ((iRet<>0) and (piLastSelected(Self)<>-1)) Begin
// select everything in between
// do not mark this as the last current row,
// the first item of the shift remains
If (iCurrent > piLastSelected(Self)) Begin
Move (piLastSelected(Self)) to iFrom
Move iCurrent to iTo
End
Else Begin
Move iCurrent to iFrom
Move (piLastSelected(Self)) to iTo
End
Move 0 to iCount
For iItem from iFrom to (iTo+3)
// Add to array
Move iItem to aiSelected[iCount]
Increment iCount
// select
For iCol from 0 to (Line_Size(Self)-1)
Forward Send Select_Toggling (iItem+iCol) True
Loop
// next row
Add 3 to iItem
Loop
End
Else Begin
// no shift or control key was pressed
// Update last selected with this item
Move iCurrent to aiSelected[0]
Set piLastSelected to iCurrent
// Select Current item
For iCol from 0 to (Line_Size(Self)-1)
Forward Send Select_Toggling (iCurrent+iCol) iState
Loop
End
End
Set Dynamic_Update_State to iUpdate
Set paiSelected to aiSelected
End_Procedure // Select_Toggling
Procedure Mouse_Up Integer iWindowNumber Integer iPosition
Integer iCol
Move (Mod(iWindowNumber , Line_Size(Self))) to iCol
Forward Send Mouse_Up iWindowNumber iPosition
If (iCol<>1) Send Select_Toggling 0 False
End_Procedure // Mouse_Up
// END MULTI-SELECT CODE
//Sample method of how to fill a grid
Procedure DoFillGrid
Integer iRow iMaxRows
Move 20 to iMaxRows
For iRow from 0 to iMaxRows
Send Add_Item Msg_None ""
Send Add_Item Msg_None ("Col 1, row " + String (iRow))
Send Add_Item Msg_None ("Col 2, row " + String (iRow))
Send Add_Item Msg_None ("Col 3, row " + String (iRow))
Set Entry_State item (iRow*4) to False
Set ItemColor item (iRow*4) to clBtnFace
Loop
End_Procedure // DoFillgrid
Send DoFillgrid
End_Object // oGrid1
Object oButton1 is a Button
Set Size to 14 70
Set Location to 151 44
Set Label to "Show Selection"
// Example on how to get selected rows
Procedure OnClick
Integer[] aiSelected
Integer iItem iCount
Get paiSelected of oGrid1 to aiSelected
Move (SizeOfArray(aiSelected)) to iCount
Showln "Selected Row base_item(s) are"
For iItem from 0 to (iCount-1)
Showln (Character(9)) aiSelected[iItem]
Loop
End_Procedure // OnClick
End_Object // oButton1