首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 拖放程式設計進階(二):拖放方法、開發步驟與 TabSet 重新排序實戰

     編輯:Delphi

承接上篇,本文深入 TControl 三大拖放方法、標準化四階段開發流程,並以 TabSet 標籤拖曳重新排序為完整案例展示實作細節。

一、三大核心拖放方法

方法用途關鍵參數
BeginDrag(Immediate: Boolean)手動模式啟動拖放Immediate=True 立即開始;False 待移動 5 像素後開始(保留 OnClick)
EndDrag(Drop: Boolean)結束拖放Drop=True 在當前位置放下(目標決定是否接受);False 取消
Dragging: Boolean判斷控件是否正被拖曳唯讀屬性,常用於 OnDragOver 中依來源控件動態變更 UI

範例:拖入 Panel 區域自動取消


procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := False;
  if (Source is TLabel) and (State = dsDragEnter) then
    (Source as TLabel).EndDrag(False); // 強制取消
end;

範例:依拖曳來源動態變更表單背景色


procedure TForm1.FormActivate(Sender: TObject);
begin
  CheckBox1.DragMode := dmAutomatic;
  CheckBox2.DragMode := dmAutomatic;
  CheckBox3.DragMode := dmAutomatic;
end;

procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  if CheckBox1.Dragging then Color := clAqua;
  if CheckBox2.Dragging then Color := clYellow;
  if CheckBox3.Dragging then Color := clLime;
end;

二、拖放功能開發四階段標準流程

  1. 啟動拖放:DragMode := dmAutomatic 或 OnMouseDown 中呼叫 BeginDrag
  2. 接收拖放項目:目標控件 OnDragOver 設定 Accept := True/False,可依 Source 型別、State 決定
  3. 放下拖放項目:目標控件 OnDragDrop 執行實際資料移轉/排序邏輯
  4. 終止拖放:來源控件 OnEndDrag 清理暫存狀態(Target <> nil 表示成功放下)

三、實戰案例:TabSet 標籤拖曳重新排序

需求: 執行期將標籤拖至新位置,Tabs 字串清單自動重新排序。

1. 介面佈局

放置 TabSet1,DragMode := dmManual(手動控制)。

2. 啟動拖放:OnMouseDown


procedure TForm1.TabSet1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  DragItem: Integer;
begin
  if Button = mbLeft then begin
    DragItem := TabSet1.ItemAtPos(Point(X, Y)); // 取得點擊處標籤索引
    if (DragItem > -1) and (DragItem < TabSet1.Tabs.Count) then
      TabSet1.BeginDrag(False); // False:移動 5 像素後才開始,保留單擊選中功能
  end;
end;

3. 接收判斷:OnDragOver


procedure TForm1.TabSet1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := (Source = TabSet1); // 僅接受自身標籤拖放
end;

4. 放下與重新排序:OnDragDrop


procedure TForm1.TabSet1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  SrcIndex, DstIndex: Integer;
  Temp: string;
begin
  if Source = TabSet1 then begin
    SrcIndex := TabSet1.Tag; // 儲存於 OnDragOver 或額外變數
    DstIndex := TabSet1.ItemAtPos(Point(X, Y));
    if (DstIndex >= 0) and (DstIndex <> SrcIndex) then begin
      Temp := TabSet1.Tabs[SrcIndex];
      TabSet1.Tabs.Delete(SrcIndex);
      TabSet1.Tabs.Insert(DstIndex, Temp);
      TabSet1.TabIndex := DstIndex; // 同步選中
    end;
  end;
end;

關鍵技巧: OnDragOver 中將 SrcIndex := TabSet1.ItemAtPos(Point(X, Y)) 暫存於 TabSet1.Tag 或表單私有欄位,供 OnDragDrop 使用。

5. 終止清理:OnEndDrag


procedure TForm1.TabSet1EndDrag(Sender, Target: TObject; X, Y: Integer);
begin
  // Target <> nil 表示成功放下,可做後續處理
  // 此處無額外清理需求
end;

四、進階技巧與注意事項

  • 自訂拖放游標: 來源控件 DragCursor := crMultiDrag 或自訂游標資源
  • 跨表單/應用程式拖放: 需使用 TDataObject 實作 IDataObject 介面,支援 CF_TEXT/CF_HDROP 等格式
  • DragKind := dkDock 可實現停靠/浮動面板(DockSite/DragKind 機制)
  • 效能:大量項目拖放時,OnDragOver 避免複雜運算,必要時用 BeginUpdate/EndUpdate

五、完整事件對照表

掌握四階段流程與三大方法,配合 ItemAtPos、Tabs.Insert/Delete 等字串清單操作,即可輕鬆實現直觀的拖放重新排序介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
事件觸發時機典型用途
OnDragOver拖曳進入/移動目標控件上空設定 Accept、視覺回饋
OnDragDrop在目標控件上釋放滑鼠資料移轉、排序、複製
OnEndDrag拖放結束(來源控件)清理、成功/失敗後處理
OnStartDrag拖放啟動前(僅 dmAutomatic)初始化拖放資料物件