Нажмите на ячейку в TGRIDPANEL
-
26-10-2019 - |
Вопрос
у меня есть 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()
.
Любая помощь будет очень оценена.
РЕДАКТИРОВАТЬ: Изменено переменное результат на MyControl, чтобы избежать путаницы.
Решение
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;
Другие советы
Вот оптимизация подхода 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;