Friday, January 16, 2015

Tick/Untick a checkbox on Grid with AllowCellSelection = .F.

Normally, when we want to put a checkbox on grid for the purpose of ticking and unticking it, then most probably most of you do it this way:

  • Set AllowCellSelection = .T.
  • Drill to every textbox object inside each columns and put under When method Return(.f.).  That is to prohibit the cell in getting focus

An alternative way is to set AllowCellSelection = .F. and use grid's double-click on toggling the value of the logical field bound to that checkbox, then perform a grid refresh

While any of the two will work, I will be showing here an alternative to that where the Grid's AllowCellSelection will still be set to .F. disallowing individual objects inside to receive a focus yet will allow you to click on the checkbox as if the checkbox can really be selected.

The trick is really simple.  Here are the codes:

Local oForm
Read Events

Define Class Form1 As Form
      Height = 460
      Width = 500
      AutoCenter = .T.
      Caption = 'Ticking Checkbox on Grid with AllowSelection = .F.'
      ShowTips = .T.

      Add Object grid1 As Grid With ;
            GridLines = 0, ;
            Height = 400, ;
            Left = 10, ;
            Top = 50, ;
            Width = 490,;
            GridLines = 3,;
            DeleteMark = .F.,;
            ScrollBars = 2,;
            ColumnCount = 3,;
            AllowCellSelection = .F.

      Add Object label2 As Label With ;
            top = 10,;
            left = 15,;
            Height = 36,;
            caption = 'This is a simple trick on allowing the checkbox object to be ticked even though '+;
            "the grid's AllowCellSelection is set to .F.  The trick is on MouseDown",;
            WordWrap = .T.,;
            Width = 570

      Procedure Load
            Close Databases All
            Select .F. As xSelect, cust_id, company From (Home(2)+"data\customer") Into Cursor junk Readwrite

      Procedure grid1.Init
      With This
            .RecordSourceType = 1
            .RecordSource = 'junk'
            .Column3.Width = 360
            With .Column1
                  .CurrentControl = "check1"
                  .Sparse = .F.
                  .check1.Caption = ''
                  .check1.Visible = .T.
                  .Width = 20


      Procedure grid1.MouseDown
      Lparameters nButton, nShift, nXCoord, nYCoord
      Local lnWhere, lnRelRow, lnRelCol
      If m.lnRelCol = 1
            Replace xSelect With !xSelect In junk

      Procedure Destroy
            Clear Events


Said trick will give the grid an illusion that there are two groups, i.e., 1st is the checkbox and the 2nd is the rest of the columns.  And for those new with Grid Dynamic Properties as well, just to highlight the selected (ticked) records, I use DynamicBackColor here.

Hope you'll find this useful! Cheers!



    1. Haven't seen that. Thanks! Still, both of our approaches use Relative Column and that, later I found out, will fail when the columns are reordered. Here is a much better way that allows column reordering: