ProgressBar en el subelemento tListview Delphi
-
20-09-2019 - |
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;
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.