Immer die Zelle angeklickt im TGridPanel
-
26-10-2019 - |
Frage
Ich habe eine TGridPanel
auf ein Formular und möchten, fügen Sie ein Steuerelement auf eine bestimmte "Zelle", die angeklickt wird.
Kann ich den Punkt einfach genug:
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;
Ich wahrscheinlich nicht brauchen, die if ControlAtPos(P) = nil then
Zeile, aber ich möchte sicherstellen, dass ich bin nicht einfügen eines Steuerelements in einer Zelle, die bereits eine in ihm.
So...welchen code muss ich verwenden, um InsCol und InsRow?Ich habe oben und unten TGridPanel
und TControlCollection
Klasse code und kann nichts finden, dass mir eine Spalte oder eine Zeile Wert von Maus-Koordinaten.Noch ist Ihre zu sein scheinen einem relevanten Ereignis zu verwenden, andere als OnDblClick()
.
Jede Hilfe würde sehr geschätzt werden.
EDIT:Variable Ergebnis zu MyControl um Verwirrung zu vermeiden.
Lösung
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;
Andere Tipps
Hier ist eine Optimierung der Ravaut123 Ansatz (sollte sehr VIEL schneller für größere Netze).Diese Funktion gibt die X/Y-grid-Position in einem TPoint.Wenn der Benutzer angeklickt hat eine gültige Spalte aber nicht ein gültiges Zeile, dann die gültige Spalte Informationen ist immer noch zurückgegeben, und das gleiche gilt für Zeilen.Also es ist nicht "alles oder nichts" (gültig Zelle oder ungültige Zelle).Diese Funktion übernimmt das raster ist "regular" (jede Spalte hat die gleiche Zeile Höhe wie die erste Spalte, ebenso jede Zeile hat die gleiche Breite Spalte in der ersten Zeile).Wenn das Gitter nicht regelmäßig dann Ravaut123 die Lösung ist die bessere Wahl.
// 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;