Trascina i controlli di caduta in un gridpanel
-
27-10-2019 - |
Domanda
Ho preso in giro il trascinamento e la caduta dei controlli in un pannello a griglia a Delphi 2010. Spostare un pannello/pulsante/wattever Il contenuto è da una cella a un'altra cella. Sostituire luoghi esistenti o di scambio. Non ho capito come so su quale cella è stata eliminata perché funzionano con indici di colonna e anche indici di riga.
Quindi se ho un gridpanel che ha 3 colonne e 3 righe e ho un pulsante nella cella 1/1 ... e trascino quel pulsante da 1/1 a 3/3 come posso ottenere quella posizione della cella dal dragdrop evento? Ottengo le coordini X, Y sulla goccia, ma come posso determinare la cella da quello?
Soluzione
Puoi usare TGridPanel.CellRect
Per ottenere il rettangolo di delimitazione per ciascuna delle celle. Ecco un esempio di come usare CellRect
:
// GP: TGridPanel
// This is the "OnDragDrop" handler.
procedure TForm13.GPDragDrop(Sender, Source: TObject; X, Y: Integer);
var DropPoint: TPoint;
CellRect: TRect;
i_col, i_row: Integer;
begin
if Source = Panel1 then // Simple test, is this a drop I want to handle?
begin
DropPoint := Point(X, Y); // Where did the suer drop? We need this so we can easily call PtInRect
for i_col := 0 to GP.ColumnCollection.Count-1 do
for i_row := 0 to GP.RowCollection.Count-1 do
begin
CellRect := GP.CellRect[i_col, i_row]; // Get the bounding rect for Col[i_col, i_row]
if PtInRect(CellRect, DropPoint) then
begin
// Panel1 was dropped over Cell[i_col, i_row]
end;
end;
end;
end;
Altri suggerimenti
Sulla base della risposta di Cosmin (che è un bel punto di partenza ma non funziona nella vita reale).
Il mio codice è in C ++ ma poiché si tratta di un "clone" della risposta di Consmin, gli utenti di Delphi possono capirlo facilmente (e vedere cosa è stato cambiato).
PS: Nota che trascino tpanel invece di tbuttons (un cambiamento molto minore).
void __fastcall TfrmVCL::ButtonDragDrop(TObject *Sender, TObject *Source, int X, int Y)
{
TRect CurCellRect;
TRect DestCellRect;
int Col;
int Row;
int srcCol; int srcRow;
int destCol; int destRow;
int srcIndex; int destIndex;
TPanel *SrcBtn;
TPanel *DestBtn;
SrcBtn = dynamic_cast<TPanel *>(Source);
if (SrcBtn)
{
int ColCount = GridPnl->ColumnCollection->Count ;
int RowCount = GridPnl->RowCollection->Count ;
// SOURCE
srcIndex = GridPnl->ControlCollection->IndexOf( SrcBtn );
srcCol = GridPnl->ControlCollection->Items[ srcIndex ]->Column; // the column for the dragged button
srcRow = GridPnl->ControlCollection->Items[ srcIndex ]->Row;
// DESTINATION
// we get coordinates of the button I drag onto
DestBtn= dynamic_cast<TPanel *>(Sender);
if (!DestBtn) return;
destIndex = GridPnl->ControlCollection->IndexOf( DestBtn );
destCol = GridPnl->ControlCollection->Items[ destIndex ]->Column; // the column for the dragged button
destRow = GridPnl->ControlCollection->Items[ destIndex ]->Row;
DestCellRect = GridPnl->CellRect[ destCol ][ destRow ];
// Check all cells
for ( Col = 0 ; Col < ColCount ; Col++ )
{
for ( Row = 0 ; Row < RowCount ; Row++ )
{
// Get the bounding rect for this cell
CurCellRect = GridPnl->CellRect[ Col ][ Row ];
if (IntersectRect_ForReal(DestCellRect, CurCellRect))
{
GridPnl->ControlCollection->Items[srcIndex]->SetLocation(Col, Row, false);
return;
}
else
lblCurCellRect->Caption= "NO HIT";
}
}
}
}