Skip to main content

Example: Walking through Levels

  • 3 minutes to read

The following example shows how you can move focus between nesting levels in a grid control.

Assume that you have two buttons on your form: ButtonLevelUp and ButtonLevelDown. Clicking these buttons moves focus to upper and lower levels respectively.

Clicking the ButtonLevelUp button moves focus from a nesting level to an upper level. If the currently focused record belongs to a detail, this action moves focus to the master row owning the detail. If grouping is applied and the current record belongs to a data group, a click on this button moves focus to the immediate group row containing the record.

The following code shows the OnClick event handler of the ButtonLevelUp button. To get a parent record for the focused record, we use the ParentRecord property. The Focused property of a record allows you to move focus to this record.

procedure TForm1.ButtonLevelUpClick(Sender: TObject);
var
  ARecord: TcxCustomGridRecord;
begin
  with TcxCustomGridTableView(Grid.FocusedView) do
  begin
    ARecord := Controller.FocusedRecord;
    if Assigned(ARecord) then
    begin
      ARecord := ARecord.ParentRecord;
      if Assigned(ARecord) then
        ARecord.Focused := True;
    end;
  end;
end;

When the end-user clicks the ButtonLevelDown button, focus moves from an upper level to a nesting level. If a group row is focused, it is expanded first and then the next record is focused. If a master row is focused, it is also expanded and then the focus moves to the first record in the corresponding detail View.

The following code shows the OnClick event for the ButtonLevelDown button. The GetFirstChild function returns the first child for a given record. Note that before GetFirstChild is called, the record is expanded first. This ensures that the GetFirstFocusableChild function and the Records[ARecord.Index + 1] statement will return the appropriate child records.

GetFirstFocusableChild returns a child record for a master row. The Records[ARecord.Index + 1] statement returns a child record for a group row.

procedure TForm1.ButtonLevelDownClick(Sender: TObject);
  function GetFirstChild(ARecord: TcxCustomGridRecord): TcxCustomGridRecord;
  begin
    if ARecord is TcxGridMasterDataRow then
      Result := ARecord.GetFirstFocusableChild
    else
      if ARecord is TcxGridGroupRow then
        Result := ARecord.ViewData.Records[ARecord.Index + 1]
      else
        Result := nil;
  end;
var
  ARecord: TcxCustomGridRecord;
begin
  with TcxCustomGridTableView(Grid.FocusedView) do
  begin
    ARecord := Controller.FocusedRecord;
    if Assigned(ARecord) then
    begin
      ARecord.Expand(False);
      ARecord := Controller.FocusedRecord;
      ARecord := GetFirstChild(ARecord);
      if Assigned(ARecord) then
        ARecord.Focused := True;
    end;
  end;
end;