Mise en la cellule cliqué sur un TGridPanel
-
26-10-2019 - |
Question
J'ai un TGridPanel
sur un formulaire et que vous souhaitez ajouter un contrôle à un spécifique « cellule » qui est cliqué.
Je peux obtenir le point assez facilement:
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;
Je ne doute pas besoin de la ligne de if ControlAtPos(P) = nil then
, mais je veux vous assurer que je ne suis pas d'insérer un contrôle dans une cellule qui a déjà un en elle.
Alors ... quel code dois-je utiliser pour obtenir InsCol et InsRow? Je suis haut et en bas le code classe TGridPanel
et de TControlCollection
et ne trouve rien qui me donnera une valeur de colonne ou une ligne de coordonnées de la souris. Ni ne leur semble être un événement pertinent d'utiliser autre que OnDblClick()
.
Toute aide serait grandement appréciée.
EDIT:. Changé Résultat variable MyControl pour éviter toute confusion
La solution
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;
Autres conseils
Voici une optimisation de l'approche Ravaut123 (devrait être beaucoup plus rapide pour les réseaux de grande taille). Cette fonction retourne l'emplacement de la grille X / Y dans un TPoint. Si l'utilisateur a cliqué sur une colonne valide mais pas une ligne valide, les informations de colonne valide est toujours retourné, et va de même pour les lignes. Il est donc pas « tout ou rien » (cellule valide ou une cellule non valide). Cette fonction suppose la grille est « normal » (chaque colonne a la même hauteur de ligne que la première colonne, de même chaque ligne a la même largeur de colonne de la première rangée). Si la grille n'est pas régulière alors la solution de Ravaut123 est le meilleur choix.
// 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;