Monday, March 10, 2014

Delphi TStringGrid

Disable focus and selection in Delphi TStringGrid

The default behaviour of Delphi's TStringGrid is to initialize with the top left cell selected. You can prevent this in code as follows but it's a bad solution because future actions that want to lookup the selection will cause you to crash. It's better to leave the first row blank, set its height to -1 (as described below) and leave the selection in that row.

  NoSelection: TGridRect = (Left: 0; Top: -1; Right: 0; Bottom: -1);

constructor Whatever...
  myStringGrid.Selection := NoSelection;

That won't stop the user from clicking a cell and establishing a new selection. Disable their ability to move the selection by defining a handler for the OnSelectCell event.

procedure Whatever.mySelectCellHandler(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
  CanSelect := false;

Now the selection is fixed outside the top-left of your grid. This has the undesirable effect of painting a highlight as the user click on cells, which the software interprets as an attempt to select a range. Eliminate this with goRangSelect.

Properties > Options > goRangSelect = False

Autosize columns in a Delphi TStringGrid

In my case I have a two column grid inside a sizeable sidebar. My first column is fixed width. My second column should fill the remainder of the space. I achieve this with a timer because I was already using a timer on that page.

    m_iWidth: Integer;

constructor MyFrame.Create(...);
  m_iWidth := 0;

procedure MyFrame.myTimerEvent(Sender: TObject);
  if (m_iWidth <> myStringGrid.Width) then
    m_iWidth := myStringGrid.Width;
    myStringGrid.ColWidths[1] := myStringGrid.ClientWidth - myStringGrid.ColWidths[0] - myStringGrid.GridLineWidth;

Hide rows in a Delphi TStringGrid

You can set the row height to -1 but in my experience the row isn't hidden completely. If you're willing to rebuild the grid you can set myGrid.RowCount:=1; which has the effect of deleting all but the first row. You aren't allowed to delete the first row. You can however leave it blank and set its height to -1. To add more rows later just increase the rowCount.

  itr: Integer;
  for itr := 0 to myGrid.RowCount-1 do
    myGrid.RowHeights[itr] := -1;
{ "loggedin": false, "owner": false, "avatar": "", "render": "nothing", "trackingID": "UA-36983794-1", "description": "", "page": { "blogIds": [ 488 ] }, "domain": "", "base": "\/michael", "url": "https:\/\/\/michael\/", "frameworkFiles": "https:\/\/\/michael\/_framework\/_files.4\/", "commonFiles": "https:\/\/\/michael\/_common\/_files.3\/", "mediaFiles": "https:\/\/\/michael\/media\/_files.3\/", "tmdbUrl": "http:\/\/\/", "tmdbPoster": "http:\/\/\/t\/p\/w342" }