Delphi tListview 子项中的进度条

发布于 2024-08-17 22:11:37 字数 3288 浏览 0 评论 0原文

我一直在研究如何在 Delphi 中的 TListView 中放置进度条,并且我已经得到了一些有效的代码,但我想将其添加到 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; 

I've been looking at how to put a progress bar in a TListView in Delphi, and I've got some code that works, BUT I want to add it to a SubItem and cannot figure out how.

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.

The code I want it to work with is:

...
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; 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝咒 2024-08-24 22:11:37

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

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

但要使其发挥作用,您仍然需要列表项有一个子项。您只需在其顶部放置一个进度条,并且您已经有了执行此操作的代码。您不能将对象添加为子项;子项目始终是文本。文本可以为空,但为了知道如何阅读列表视图的屏幕阅读器的利益,如果您使用进度条的值更新文本,那就太好了。

The code you've shown doesn't really add a progress bar "to" a subitem. Rather, it takes a standalone progress bar and moves it to cover the space of the first two columns. That's what your AdjustProgressBar function does. It receives the bounding rectangle of the list item, which I think corresponds to the total width of all the columns. Then, it shifts the left side of the rectangle by the width of the first column, and it shifts the right side of the rectangle by the width of the second column.

You can adjust the coordinates of the progress bar however you want. For example, to make it cover the third column, shift the left side by the widths of the first two columns, and then set the right side to the left coordinate plus the third column's width.

But for that to work, you still need for the list item to have a subitem. You're just putting a progress bar on top of it, and you already have code to do that. You can't add an object as a subitem; a subitem is always text. The text can be blank, although for the benefit of screen readers that know how to read list views, it would be nice if you updated the text with the progress bar's value.

铁憨憨 2024-08-24 22:11:37

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

查看这篇文章

I'd take a look at the OnDrawItem and completely redraw the control myself.

Check this post.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文