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

Était-ce utile?

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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top