0

I have an FMX TStringGrid with three columns. Column 1 is a TStringColumn. Column 2 is TCurrencyColumn. Column 3 is a TPopupColumn with 3 items 'One','Two','Three'. I've also added an OnEditingDone event to show a message when Column1 is blank.

What I can't figure out is how to make the grid focus back to the cell that is blank. I have Options:Tabs=True. If I tab into Column 2 with a blank Column 1 I get the error message. However, the OnEditingDone does not set focus back to the blank cell.

How do you return to the blank cell?

Screen capture shows tabbing through a StringGrid.

video of tabbing around a string grid

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Rtti,
  FMX.Grid.Style, FMX.StdCtrls, FMX.Grid, FMX.Controls.Presentation,
  FMX.ScrollBox;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    StringColumn1: TStringColumn;
    CurrencyColumn1: TCurrencyColumn;
    PopupColumn1: TPopupColumn;
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1EditingDone(Sender: TObject; const ACol,
      ARow: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.SelectCell(0,0);
  StringGrid1.SetFocus;
end;

procedure TForm1.StringGrid1EditingDone(Sender: TObject; const ACol,
  ARow: Integer);
begin
  if ACol=0 then
    if StringGrid1.Cells[0,ARow] = '' then
    begin
      ShowMessage('Col 0 Row ' + ARow.ToString+ ' Cannot be blank');
      StringGrid1.SelectCell(0,ARow);
    end;
end;

end.
  • The `ShowMessage()` steals the input focus. Did you try adding `SetFocus()` after `SelectCell()` in your `OnEditingDone` handler? Like you do in your `OnCreate` handler. If that doesn't work, try delaying the focus change with `TThread.ForceQueue()` so it occurs after the `OnEditingDone` handler exits, eg: `ShowMessage(...); TThread.ForceQueue(nil, procedure begin StringGrid1.SelectCell(0,ARow); StringGrid1.SetFocus; end);` – Remy Lebeau Apr 01 '23 at 20:24
  • However, you didn't say which platform(s) this code is running on. `ShowMessage()` is *synchronous* only on desktop platforms, but is *asynchronous* on mobile platforms. In the latter case, use `IFMXDialogServiceAsync.ShowMessageAsync()` instead, so you can be notified when the message dialog is closed, THEN perform the focus change. – Remy Lebeau Apr 01 '23 at 20:28
  • @RemyLebeau, just adding SetFocus() did not work. Using TThread.ForceQueue does work. Thank you. – Michael Riley - AKA Gunny Apr 01 '23 at 23:54

0 Answers0