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

Delphi TListView 嵌入 ProgressBar 實作下載進度動態顯示

     編輯:Delphi

需求場景

下載管理器需在列表每一列顯示進度條。TListView (vsReport 模式) 原生不支援在子項嵌入控制項,但可動態建立 TProgressBar、設定 Parent 為 ListView、並依據 SubItem 矩形定位。

核心實作步驟

  1. ListView ViewStyle := vsReport,建立兩欄:檔案名、進度。
  2. 新增項目時,Items.Add 取得 TListItem,建立 TProgressBar,存入 Item.Data。
  3. 計算第二欄顯示矩形 (DisplayRect(drBounds) + 欄位寬度偏移),設定 ProgressBar BoundsRect。
  4. 刪除項目前先 TProgressBar(Item.Data).Free 釋放控制項,再 Items.Delete,並調整後續項目 ProgressBar 的 Top 座標。
  5. 使用 TTimer 模擬進度更新,隨機挑選項目遞增 Position。

關鍵程式碼片段

// 新增項目
procedure TForm1.AddItem(const FileName: string);
var
  Item: TListItem;
  PB: TProgressBar;
  R: TRect;
begin
  Item := ListView1.Items.Add;
  Item.Caption := FileName;
  PB := TProgressBar.Create(Self);
  PB.Parent := ListView1;
  PB.Min := 0; PB.Max := 100; PB.Position := 0;
  Item.Data := PB;
  UpdateProgressBarPos(Item);
end;

// 依據 SubItem 矩形定位 ProgressBar
procedure TForm1.UpdateProgressBarPos(Item: TListItem);
var
  PB: TProgressBar;
  R: TRect;
begin
  PB := TProgressBar(Item.Data);
  R := Item.DisplayRect(drBounds); // 第一欄矩形
  R.Left := R.Left + ListView1.Columns[0].Width; // 移至第二欄
  R.Right := R.Left + ListView1.Columns[1].Width;
  PB.BoundsRect := R;
end;

// 刪除項目
procedure TForm1.DeleteSelectedItem;
var
  Item: TListItem;
  i: Integer;
  PB: TProgressBar;
begin
  Item := ListView1.Selected;
  if Item = nil then Exit;
  TProgressBar(Item.Data).Free;
  ListView1.Items.Delete(Item.Index);
  // 後續項目上移
  for i := Item.Index to ListView1.Items.Count - 1 do
  begin
    PB := TProgressBar(ListView1.Items[i].Data);
    PB.Top := PB.Top - PB.Height;
  end;
end;

// Timer 更新進度
procedure TForm1.Timer1Timer(Sender: TObject);
var
  Item: TListItem;
  PB: TProgressBar;
begin
  if ListView1.Items.Count = 0 then Exit;
  Item := ListView1.Items[Random(ListView1.Items.Count)];
  PB := TProgressBar(Item.Data);
  if PB.Position < PB.Max then PB.StepIt else PB.Position := 0;
end;

注意事項

  • ListView 捲動、調整欄寬、視窗大小改變時,需重新計算所有 ProgressBar 位置 (處理 OnResize、OnColumnClick、OnScroll 等事件)。
  • 大量項目 (>數百) 會建立大量視窗控制項,影響效能;可考慮 Alcinoe 或 EMC 等第三方虛擬化列表元件,或自繪進度條 (OnCustomDrawSubItem) 避免建立真實控制項。
  • 記得在表單銷毀時釋放所有 Item.Data 中的 ProgressBar。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved