Domanda

Ho un TGridPanel su una forma e desiderio di aggiungere un controllo a una "cella" specifico che viene cliccato.

posso ottenere il punto abbastanza facilmente:

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;

Probabilmente non c'è bisogno della linea if ControlAtPos(P) = nil then, ma voglio fare in modo che non sto inserendo un controllo in una cella che ha già uno in esso.

Quindi ... quale codice devo utilizzare per ottenere inscol e InsRow? Sono stato su e giù per il codice TGridPanel e la classe TControlCollection e non riesco a trovare nulla che mi darà un valore di colonna o riga da coordinate del mouse. Né la loro sembra essere un evento rilevante per uso diverso da quello OnDblClick().

Qualsiasi aiuto sarebbe molto apprezzato.

EDIT:. Cambiato Risultato variabile MyControl per evitare confusione

È stato utile?

Soluzione

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;

Altri suggerimenti

Ecco un'ottimizzazione dell'approccio di Ravaut123 (dovrebbe essere molto più veloce per le griglie più grandi). Questa funzione restituisce la posizione Y X / griglia in una TPoint. Se l'utente fa clic su una colonna valida ma non una riga valida, quindi le informazioni di colonna valida è ancora tornato, e lo stesso vale per le righe. Quindi non è "tutto o niente" (cella valido o di cella non valido). Questa funzione presuppone la griglia è "normale" (ogni colonna ha la stessa altezza della riga della prima colonna, analogamente ogni riga ha la stessa larghezza della colonna come prima riga). Se la griglia non è regolare, allora la soluzione di Ravaut123 è la scelta migliore.

// 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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top