0

我一直在研究如何TListView在 Delphi 中放置进度条,并且我有一些可以工作的代码,但我想将它添加到 SubItem 并且无法弄清楚如何。

object Form1: TForm1
  Left = 221
  Top = 113
  Caption = 'Form1'
  ClientHeight = 203
  ClientWidth = 482
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  DesignSize = (
    482
    203)
  PixelsPerInch = 96
  TextHeight = 13
  object ListView1: TListView
    Left = 16
    Top = 16
    Width = 449
    Height = 177
    Anchors = [akLeft, akTop, akRight, akBottom]
    Columns = <>
    FullDrag = True
    TabOrder = 0
    OnCustomDrawItem = ListView1CustomDrawItem
  end
end
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, CommCtrl;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure ListView1CustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
  private
    { Private declarations }
    procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY;
    procedure AdjustProgressBar(item: TListItem; r: TRect);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Byte;
  r: TRect;
  pb: TProgressBar;
begin
  Listview1.Columns.Add.Width := 100;
  Listview1.Columns.Add.Width := 200;
  Listview1.ViewStyle := vsReport;

  Randomize;
  for i:=0 to 40 do
  begin
    Listview1.Items.Add.Caption := 'Texte ' + IntToStr(i);
    r := Listview1.Items[i].DisplayRect(drBounds);
    pb := TProgressBar.Create(Self);
    pb.Parent := Listview1;
    pb.Position := Random(pb.Max);
    Listview1.Items[i].Data := pb;
    AdjustProgressBar(Listview1.Items[i], r);
  end;end;

  procedure TForm1.WMNotify(var Message: TWMNotify);
var
  i: Integer;
  r: TRect;
begin

  case Message.NMHdr.code of
    HDN_ITEMCHANGED, HDN_ITEMCHANGING:
      begin
        for i:=0 to Listview1.Items.Count-1 do
        begin
          r := Listview1.Items[i].DisplayRect(drBounds);
          AdjustProgressBar(Listview1.Items[i], r);
        end;

        ListView1.Repaint;
      end;end;
  inherited;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  r: TRect;
  pb: TProgressBar;
begin
  r := Item.DisplayRect(drBounds);
  if r.Top>=Listview1.BoundsRect.Top then
    AdjustProgressBar(Item, r);
end;

procedure TForm1.AdjustProgressBar(item: TListItem; r: TRect);
var
  pb: TProgressBar;
begin
  r.Left := r.Left + Listview1.columns[0].Width;
  r.Right := r.Left + Listview1.columns[1].Width;
  pb := item.Data;
  pb.BoundsRect := r;
end;

end.

我希望它使用的代码是:

...
with listview1.Items.Add do
begin
  Caption := IntToStr(listview1.Items.Count);
  SubItems.Add('blah');
  SubItems.Add('blah');
  SubItems.Add('blah');
  {Add SubItem Progress Bar here Position 4 out of 10}
end; 
4

2 回答 2

4

您显示的代码并没有真正将进度条“添加到”子项。相反,它需要一个独立的进度条并将其移动以覆盖前两列的空间。这就是你的AdjustProgressBar功能所做的。它接收列表项的边界矩形,我认为它对应于所有列的总宽度。然后,它将矩形的左侧移动第一列的宽度,并将矩形的右侧移动第二列的宽度。

您可以根据需要调整进度条的坐标。例如,要使其覆盖第三列,将左侧移动前两列的宽度,然后将右侧设置为左侧坐标加上第三列的宽度。

但要使其正常工作,您仍然需要列表项有一个子项。你只是在它上面放了一个进度条,而且你已经有代码可以做到这一点。您不能将对象添加为子项;子项始终是文本。文本可以是空白的,尽管为了知道如何阅读列表视图的屏幕阅读器的利益,如果您使用进度条的值更新文本会很好。

于 2010-01-15T06:36:23.187 回答
2

我会看一下 OnDrawItem 并自己完全重绘控件。

检查这篇文章

于 2011-03-28T12:25:12.083 回答