Получение щелчка по ячейке в TGridPanel - PullRequest
2 голосов
/ 30 ноября 2011

У меня есть TGridPanel в форме, и я хочу добавить элемент управления к определенной "ячейке", по которой щелкают.

Я могу достаточно легко получить точку:

procedure TForm1.GridPanel1DblClick(Sender: TObject);
var
  P : TPoint;
  InsCol, InsRow : Integer;
begin
  P := (Sender as TGridPanel).ScreenToClient(Mouse.CursorPos);
  if (Sender as TGridPanel).ControlAtPos(P) = nil then
    begin
      InsCol := ???;
      InsRow := ???;
      (Sender as TGridPanel).ControlCollection.AddControl(MyControl, InsCol, InsRow)
    end;
end;

Мне, вероятно, не нужна строка if ControlAtPos(P) = nil then, но я хочу убедиться, что я не вставляю элемент управления в ячейку, в которой он уже есть.

Итак ... какой код делатьЯ использую, чтобы получить InsCol и InsRow?Я перебираю код класса TGridPanel и TControlCollection и не могу найти ничего, что даст мне значение столбца или строки из координат мыши.Также не похоже, что они являются релевантным событием для использования, кроме OnDblClick().

. Любая помощь будет принята с благодарностью.

РЕДАКТИРОВАТЬ: Изменена переменная Result для MyControl, чтобы избежать путаницы.

Ответы [ 2 ]

3 голосов
/ 30 ноября 2011
procedure TForm1.GridPanel1Click(Sender: TObject);
var
  P: TPoint;
  R: TRect;
  InsCol, InsRow : Integer;
begin
  P := (Sender as TGridPanel).ScreenToClient(Mouse.CursorPos);
  for InsCol := 0 to GridPanel1.ColumnCollection.Count - 1 do
  begin
    for InsRow := 0 to GridPanel1.RowCollection.Count - 1 do
    begin
      R:= GridPanel1.CellRect[InsCol,InsRow];
      if PointInRect(P,R) then
      begin
        ShowMessage (Format('InsCol = %s and InsRow = %s.',[IntToStr(InsCol), IntToStr(InsRow)]))
      end;
    end;
  end;


end;

function TForm1.PointInRect(aPoint: TPoint; aRect: TRect): boolean;
begin
  begin
    Result:=(aPoint.X >= aRect.Left  ) and
            (aPoint.X <  aRect.Right ) and
            (aPoint.Y >= aRect.Top   ) and
            (aPoint.Y <  aRect.Bottom); 
  end;
end;
0 голосов
/ 02 декабря 2011

Вот оптимизация подхода Ravaut123 (должна быть НАМНОГО быстрее для больших сеток). Эта функция возвращает местоположение сетки X / Y в TPoint. Если пользователь щелкнул допустимый столбец, но не допустимую строку, то верная информация о столбце по-прежнему возвращается, и то же самое относится и к строкам. Так что это не «все или ничего» (действительная ячейка или недействительная ячейка). Эта функция предполагает, что сетка является «регулярной» (каждый столбец имеет ту же высоту строки, что и первый столбец, также каждая строка имеет такую ​​же ширину столбца, что и первая строка). Если сетка не является регулярной, то решение Ravaut123 является лучшим выбором.

// APoint is a point in local coordinates for which you want to find the cell location.
function FindCellInGridPanel(AGridPanel: TGridPanel; const APoint: TPoint): TPoint;
var
  ICol, IRow : Integer;
  R : TRect;
begin
  Result.X := -1;
  Result.Y := -1;
  for ICol := 0 to AGridPanel.ColumnCollection.Count - 1 do
    begin
      R := AGridPanel.CellRect[ICol, 0];
      if (APoint.X >= R.Left) and (APoint.X <= R.Right) then
        begin
          Result.X := ICol;
          Break;
        end;
    end;
  for IRow := 0 to AGridPanel.RowCollection.Count - 1 do
    begin
      R := AGridPanel.CellRect[0, IRow];
      if (APoint.Y >= R.Top) and (APoint.Y <= R.Bottom) then
        begin
          Result.Y := IRow;
          Break;
        end;
    end;
end;
...