Multi-row select for Grid control
From DataFlex Wiki
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