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

Delphi 實戰:用 TListView 顯示數據庫內容(vsReport 模式完整指南)

     編輯:Delphi

目標

在 TListView 的 vsReport (詳細報表) 模式下,動態創建列標題並逐行填充數據集記錄,實現類似 TDBGrid 但更輕量、可定制的數據展示。

完整實現代碼

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBTables, ComCtrls;

type
  TForm1 = class(TForm)
    Query1: TQuery;
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  Col: TListColumn;
  Item: TListItem;
begin
  // 1. 設置數據源 (DBDEMOS 範例數據庫)
  Query1.DatabaseName := 'DBDEMOS';
  Query1.SQL.Text := 'SELECT * FROM country';
  Query1.Active := True;

  // 2. 切換到報表模式
  ListView1.ViewStyle := vsReport;
  ListView1.ReadOnly := True;
  ListView1.RowSelect := True;

  // 3. 動態創建列:字段名作為標題
  for i := 0 to Query1.FieldCount - 1 do
  begin
    Col := ListView1.Columns.Add;
    Col.Caption := Query1.Fields[i].FieldName;
    Col.Width := 120; // 默認寬度,可根據字段類型調整
    Col.Alignment := taLeftJustify;
  end;

  // 4. 填充數據行
  Query1.First;
  while not Query1.Eof do
  begin
    Item := ListView1.Items.Add;
    // 第一列用 Caption
    Item.Caption := Query1.Fields[0].AsString;
    // 其餘列用 SubItems
    for i := 1 to Query1.FieldCount - 1 do
      Item.SubItems.Add(Query1.Fields[i].AsString);
    Query1.Next;
  end;
end;

end.

DFM 關鍵屬性

object Form1: TForm1
  ClientHeight = 400
  ClientWidth = 600
  Caption = 'TListView 數據庫演示'
  object ListView1: TListView
    Align = alClient
    ViewStyle = vsReport
    ReadOnly = True
    RowSelect = True
    TabOrder = 0
  end
  object Query1: TQuery
    Left = 24
    Top = 24
  end
end

核心 API 對照表

任務API說明
設置視圖模式ViewStyle := vsReportvsIcon/vsSmallIcon/vsList/vsReport
添加列Columns.Add → TListColumn返回新列對象,設 Caption/Width/Alignment
添加行Items.Add → TListItem返回新行對象
第一列數據Item.Caption字串
第 2~N 列數據Item.SubItems.Add/Strings[i]TStrings 集合,索引 0 對應第 2 列
清空所有Items.Clear / Columns.Clear

進階增強技巧

1. 列寬自適應內容


procedure AutoSizeColumns(LV: TListView; MaxWidth: Integer = 300);
var
  i, j, W: Integer;
  Canvas: TCanvas;
begin
  Canvas := TControlCanvas.Create;
  try
    Canvas.Control := LV;
    Canvas.Font := LV.Font;
    for i := 0 to LV.Columns.Count - 1 do
    begin
      W := Canvas.TextWidth(LV.Columns[i].Caption) + 20; // 標題寬度
      for j := 0 to LV.Items.Count - 1 do
      begin
        if i = 0 then
          W := Max(W, Canvas.TextWidth(LV.Items[j].Caption) + 20)
        else if i - 1 < LV.Items[j].SubItems.Count then
          W := Max(W, Canvas.TextWidth(LV.Items[j].SubItems[i-1]) + 20);
      end;
      LV.Columns[i].Width := Min(W, MaxWidth);
    end;
  finally
    Canvas.Free;
  end;
end;
// 填充數據後調用
AutoSizeColumns(ListView1);

2. 交替行顏色 (斑馬紋)


procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem;
  State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if Odd(Item.Index) then
    Sender.Canvas.Brush.Color := clInfoBk // 淺黃
  else
    Sender.Canvas.Brush.Color := clWindow; // 白
end;
// 設置 ListView1.OwnerDraw := True 並綁定 OnCustomDrawItem

3. 大數據量優化:虛擬模式 (OwnerData)


// 適合 10萬+ 行,不預存 Items,按需請求
ListView1.OwnerData := True;
ListView1.Items.Count := Query1.RecordCount; // 設置虛擬行數

// OnData 事件提供單元格文本
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Query1.RecNo := Item.Index + 1;
  Item.Caption := Query1.Fields[0].AsString;
  for i := 1 to Query1.FieldCount - 1 do
    Item.SubItems.Add(Query1.Fields[i].AsString);
end;

4. 列排序支援


var
  FSortColumn: Integer = -1;
  FSortAscending: Boolean = True;

procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
  if FSortColumn = Column.Index then
    FSortAscending := not FSortAscending
  else
  begin
    FSortColumn := Column.Index;
    FSortAscending := True;
  end;
  // 這裡需重新查詢數據庫 ORDER BY 對應字段,或用 ClientDataSet 內存排序
  RefreshData;
end;

常見問題排查

現象原因解決
列不顯示ViewStyle ≠ vsReport設置 ListView1.ViewStyle := vsReport
數據只顯示第一列SubItems 未添加循環 Item.SubItems.Add(...)
運行時列標題亂碼字段名含中文/特殊字符用 DisplayLabel 或自定義標題映射
性能極慢逐行 Add 觸發重繪Items.BeginUpdate/EndUpdate 包裹填充循環
內存飆升大量行未釋放用 OwnerData 虛擬模式或分頁加載

總結

TListView + vsReport 是 Delphi 輕量級表格展示的經典選擇:**無數據綁定依賴、完全手動控制列行、擴展性極強**。掌握 Columns.Add/Items.Add/Caption/SubItems 四大核心 API,配合 BeginUpdate/EndUpdate、虛擬模式、自繪事件,即可構建從簡單查詢結果到複雜報表的各類數據展示界面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved