【问题标题】:Drag N Drop controls in a GridPanel在网格面板中拖放控件
【发布时间】:2011-07-18 14:42:23
【问题描述】:

在 delphi 2010 的网格面板中,我一直在玩弄拖放控件。将面板/按钮/无论内容从一个单元格移动到另一个单元格。更换现有的或交换的地方。我还没有弄清楚我是如何知道哪个单元格被删除的,因为它们使用列索引和行索引。

因此,如果我有一个具有 3 列和 3 行的网格面板,并且我在单元格 1/1 中有一个按钮...并且我将该按钮从 1/1 拖到 3/3,我怎样才能获得该单元格位置从拖放事件?我得到了 drop 的 x,y 坐标,但我如何从中确定单元格?

【问题讨论】:

    标签: delphi drag-and-drop gridpanel


    【解决方案1】:

    您可以使用TGridPanel.CellRect 来获取每个单元格的边界矩形。下面是一个如何使用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;
    

    【讨论】:

      【解决方案2】:

      基于 Cosmin 的回答(这是一个很好的起点,但在现实生活中不起作用)。

      我的代码是用 C++ 编写的,但由于它是 Consmin 答案的“克隆”,Delphi 用户可能很容易理解它(并查看发生了什么变化)。
      PS:请注意,我拖动 TPanels 而不是 TButtons(一个非常小的变化)。

      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";
                 }
              }
           }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多