Multi-row select for Grid control

From DataFlex Wiki
Revision as of 23:07, 22 February 2019 by Wil (talk | contribs) (add syntax highlighting)
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