Multi-row select for Grid control

From DataFlex Wiki
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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