Frage

Ich habe mit dem Ziehen und Ablegen von Steuerelementen in einem Gitterfeld in Delphi 2010 herumgespielt. Verschieben Sie ein Panel/Taste/Whateever. Der Inhalt ist von einer Zelle zu einer anderen Zelle. Ersetzen vorhandener oder tauschender Orte. Ich habe nicht herausgefunden, wie ich weiß, auf welche Zelle fallen gelassen wurde, weil sie mit Spaltenindizes und auch Zeilenindizes funktionieren.

Wenn ich also ein Gitterpanel mit 3 Spalten und 3 Zeilen habe und eine Taste in Zelle 1/1 habe ... und ich ziehe diese Taste von 1/1 in 3/3. Wie kann ich diesen Zellenort vom Dragdrop erhalten Veranstaltung? Ich bekomme die X-, Y -Koordnungen für den Tropfen, aber wie kann ich die Zelle daraus bestimmen?

War es hilfreich?

Lösung

Sie können verwenden TGridPanel.CellRect Um das Begrenzungsrechteck für jede der Zellen zu erhalten. Hier ist ein Beispiel für die Verwendung 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;

Andere Tipps

Basierend auf der Antwort von Cosmin (was ein schöner Ausgangspunkt ist, aber im realen Leben nicht funktioniert).

Mein Code ist in C ++, aber da es sich um einen "Klon" der Antwort von Consmin handelt, können Delphi -Benutzer ihn leicht verstehen (und sehen, was sich geändert hat).
PS: Beachten Sie, dass ich TPanels anstelle von Tbuttons ziehe (eine sehr geringfügige Änderung).

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";
           }
        }
     }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top