Pregunta

He estado mirando cómo poner una barra de progreso en un TListView en Delphi, y tengo un código que funciona, PERO quiero agregarlo a un SubItem y no puedo entender cómo.

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.

El código con el que quiero que funcione es:

...
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; 
¿Fue útil?

Solución

El código que ha mostrado realmente no agrega una barra de progreso "a" un subelemento.Más bien, se necesita una barra de progreso independiente y se mueve para cubrir el espacio de las dos primeras columnas.Eso es lo que tu AdjustProgressBar la función lo hace.Recibe el rectángulo delimitador del elemento de la lista, que creo que corresponde al ancho total de todas las columnas.Luego, desplaza el lado izquierdo del rectángulo según el ancho de la primera columna y desplaza el lado derecho del rectángulo según el ancho de la segunda columna.

Puedes ajustar las coordenadas de la barra de progreso como quieras.Por ejemplo, para que cubra la tercera columna, mueva el lado izquierdo según el ancho de las dos primeras columnas y luego establezca el lado derecho en la coordenada izquierda más el ancho de la tercera columna.

Pero para que eso funcione, aún necesita que el elemento de la lista tenga un subelemento.Simplemente estás poniendo una barra de progreso encima y ya tienes el código para hacerlo.No puedes agregar un objeto como un subelemento;un subelemento es siempre texto.El texto puede estar en blanco, aunque para beneficio de los lectores de pantalla que saben leer vistas de lista, sería bueno actualizar el texto con el valor de la barra de progreso.

Otros consejos

Me gustaría tener un vistazo a la OnDrawItem y volver a dibujar por completo el control de mí mismo.

este post .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top