Как удалить строку TStringGrid?

У меня есть TStringGrid, и я хочу удалить выбранную строку. Основные вещи, которые я пробовал, удаляют только последнюю строку. Как удалить произвольную строку?

Ответ 1

Если код, который вы пробовали, удаляет только последнюю строку, вы, вероятно, просто уменьшаете свойство RowCount. Это действительно делает свои модификации в конце списка строк. Имея это в виду, вы можете написать код, чтобы убедиться, что строка, которую вы больше не хотите, это тот, который находится в конце, а затем удалите последнюю строку. (Самый прямой способ - переместить строку, а там MoveRow метод, но он защищен. Если вы хотите вызвать защищенные методы, вы можете просто вызвать DeleteRow.)

Используя только публичные и опубликованные элементы, можно написать цикл, который удаляет произвольную строку. Например, здесь некоторый код, вдохновленный Часто задаваемые вопросы по Scalabium Software по этому вопросу:

procedure DeleteRow(Grid: TStringGrid; ARow: Integer);
var
  i: Integer;
begin
  for i := ARow to Grid.RowCount - 2 do
    Grid.Rows[i].Assign(Grid.Rows[i + 1]);
  Grid.RowCount := Grid.RowCount - 1;
end;

Он копирует содержимое каждой строки ниже той, которую вы хотите удалить, в строку выше. В конце цикла строка, которую вы хотите удалить, была перезаписана (рядом с ней рядом), и есть две копии последней строки. Затем он просто удаляет окончательную строку.

Чтобы удалить текущую строку сетки, вызовите функцию следующим образом:

DeleteRow(Grid, Grid.Row);

Ответ 2

Выбранная строка сетки задается свойством Row.

TCustomGrid имеет метод DeleteRow, но он защищен, поэтому вы не можете его вызывать, кроме как из потомков этого класса. Однако легко обойти это ограничение. Объявите потомок TCustomGrid, а затем введите тип управления сеткой для этого нового типа. Вызовите DeleteRow по результату.

type
  TCustomGridAccess = class(TCustomGrid) end;

procedure DeleteGridRow(g: TCustomGrid; row: Integer);
begin
  TCustomGridAccess(g).DeleteRow(row);
end;

Это работает, потому что в Delphi члены с защищенной видимостью неявно публичны в той же единице, что и объявление класса. Хотя TCustomGrid объявляется в блоке Grids, наш класс TCustomGridAccess объявляется в вашем устройстве, поэтому ваш блок имеет доступ ко всем его защищенным методам, включая DeleteRow.


Если ваша версия Delphi достаточно новая, вы можете использовать помощник класса. Помощники класса могут получить доступ к защищенным членам и не требуют применения типов для типов, не связанных с техникой.

type
  TCustomGridHelper = class helper for TCustomGrid
  public
    procedure DelRow(ARow: Integer);
  end;

procedure TCustomGridHelper.DelRow(ARow: Integer);
begin
  Self.DeleteRow(ARow);
end;

Затем просто используйте блок, в котором вы объявили помощника. Любой потомок TCustomGrid будет автоматически иметь метод DelRow, который вы можете вызвать так же, как любой другой метод сетки:

grid.DelRow(grid.Row);