Skip to main content
Table of Contents

Context menus

Attach popup menus to grid cells, switch the menu per cell, and handle direct right-click actions when a full menu would be too much UI.

Overview

TTMSFNCDataGrid can show a cell popup menu when the user right-clicks a cell. Use this for row actions, cell-specific commands, export shortcuts, or developer tools that should be available close to the selected data.

There are two common patterns:

Pattern Use it when
CellPopupMenu The user needs a menu with several actions.
OnCellRightClick A right-click should execute one simple action or show your own UI.

Assign a popup menu

Assign the menu once during form setup:

Pascal
Grid.CellPopupMenu := CellMenu;

The menu is shown for data cells when the grid receives the right-click.

Choose the menu per cell

Use OnCellBeforeShowPopupMenu when the available commands depend on the clicked row or column. The event can also cancel the popup entirely.

Choose the popup menu per cellPascalC++
procedure TForm1.GridCellBeforeShowPopupMenu(Sender: TObject;
  ACell: TTMSFNCDataGridCellCoord;
  APopupMenu: TTMSFNCDataGridPopupMenu;
  var ACanShow: Boolean);
begin
  if ACell.Row < Grid.FixedRowCount then
  begin
    ACanShow := False;
    Exit;
  end;

  if ACell.Column = NameColumn then
    Grid.CellPopupMenu := NameColumnMenu
  else
    Grid.CellPopupMenu := DefaultCellMenu;
end;
void __fastcall TForm1::GridCellBeforeShowPopupMenu(TObject *Sender,
  const TTMSFNCDataGridCellCoord &ACell,
  TTMSFNCDataGridPopupMenu *APopupMenu,
  bool &ACanShow)
{
  TTMSFNCDataGridCellCoord Cell = ACell;  // ACell is const; its getters are not
  if (Cell.Row < Grid->FixedRowCount)
  {
    ACanShow = false;
    return;
  }

  if (Cell.Column == NameColumn)
    Grid->CellPopupMenu = NameColumnMenu;
  else
    Grid->CellPopupMenu = DefaultCellMenu;
}

Typical uses:

  • Hide destructive commands on read-only rows.
  • Show column-specific commands for image, date, or memo columns.
  • Suppress the popup on fixed rows, fixed columns, group rows, or summary rows.
  • Select the clicked row before showing a row-level menu.

Handle a direct right-click

For simple cases, handle OnCellRightClick without assigning a menu:

Handle a direct cell right-clickPascalC++
procedure TForm1.GridCellRightClick(Sender: TObject;
  AColumn, ARow: Integer);
begin
  StatusBar1.SimpleText :=
    Format('Right-clicked column %d, row %d', [AColumn, ARow]);
end;
void __fastcall TForm1::GridCellRightClick(TObject *Sender,
  int AColumn, int ARow)
{
  StatusLabel->Text =
    Format("Right-clicked column %d, row %d", ARRAYOFCONST((AColumn, ARow)));
}

Combining per-cell menus with right-click feedback

This example assigns a default popup menu to the grid, overrides it for the status column with a context-sensitive menu, and updates a status bar on any right-click — using all three context-menu features together:

Combine a default menu, per-cell override, and right-click feedbackPascalC++
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Default popup menu for the whole grid
  Grid.CellPopupMenu := DefaultMenu;

  // Per-cell override wired via OnCellBeforeShowPopupMenu
  Grid.OnCellBeforeShowPopupMenu := GridCellBeforeShowPopupMenu;

  // Right-click feedback (works even when a popup menu is shown)
  Grid.OnCellRightClick := GridCellRightClick;
end;

procedure TForm1.GridCellBeforeShowPopupMenu(Sender: TObject;
  ACell: TTMSFNCDataGridCellCoord;
  APopupMenu: TTMSFNCDataGridPopupMenu;
  var ACanShow: Boolean);
begin
  // Show a special status-change menu only on the Status column
  if ACell.Column = StatusColumn then
    Grid.CellPopupMenu := StatusMenu
  else
    Grid.CellPopupMenu := DefaultMenu;
end;

procedure TForm1.GridCellRightClick(Sender: TObject;
  AColumn, ARow: Integer);
begin
  StatusBar1.SimpleText :=
    Format('Right-clicked column %d, row %d', [AColumn, ARow]);
end;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  // Default popup menu for the whole grid
  Grid->CellPopupMenu = DefaultMenu;

  // Per-cell override wired via OnCellBeforeShowPopupMenu
  Grid->OnCellBeforeShowPopupMenu = GridCellBeforeShowPopupMenu;

  // Right-click feedback (works even when a popup menu is shown)
  Grid->OnCellRightClick = GridCellRightClick;
}

void __fastcall TForm1::GridCellBeforeShowPopupMenu(TObject *Sender,
  const TTMSFNCDataGridCellCoord &ACell,
  TTMSFNCDataGridPopupMenu *APopupMenu,
  bool &ACanShow)
{
  TTMSFNCDataGridCellCoord Cell = ACell;  // ACell is const; its getters are not
  // Show a special status-change menu only on the Status column
  if (Cell.Column == StatusColumn)
    Grid->CellPopupMenu = StatusMenu;
  else
    Grid->CellPopupMenu = DefaultMenu;
}

void __fastcall TForm1::GridCellRightClick(TObject *Sender,
  int AColumn, int ARow)
{
  StatusLabel->Text =
    Format("Right-clicked column %d, row %d", ARRAYOFCONST((AColumn, ARow)));
}
  • TTMSFNCDataGrid.CellPopupMenu
  • OnCellBeforeShowPopupMenu
  • OnCellRightClick
  • TTMSFNCDataGridCellCoord

See also