ProgressBar Nella voce secondaria tListview Delphi
-
20-09-2019 - |
Domanda
Ho cercato come inserire una barra di avanzamento in un file TListView
in Delphi e ho del codice che funziona, MA voglio aggiungerlo a un sottoelemento e non riesco a capire come.
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.
Il codice con cui voglio che funzioni è:
...
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;
Soluzione
Il codice che hai mostrato non aggiunge realmente una barra di avanzamento "a" un elemento secondario.Piuttosto, richiede una barra di avanzamento autonoma e si muove per coprire lo spazio delle prime due colonne.Questo è ciò che il tuo AdjustProgressBar
la funzione fa.Riceve il rettangolo di delimitazione dell'elemento dell'elenco, che penso corrisponda alla larghezza totale di tutte le colonne.Quindi sposta il lato sinistro del rettangolo della larghezza della prima colonna e sposta il lato destro del rettangolo della larghezza della seconda colonna.
Puoi regolare le coordinate della barra di avanzamento come preferisci.Ad esempio, per coprire la terza colonna, sposta il lato sinistro in base alla larghezza delle prime due colonne, quindi imposta il lato destro sulla coordinata sinistra più la larghezza della terza colonna.
Ma affinché funzioni, è comunque necessario che l'elemento dell'elenco abbia un elemento secondario.Stai semplicemente inserendo una barra di avanzamento sopra e hai già il codice per farlo.Non puoi aggiungere un oggetto come elemento secondario;un elemento secondario è sempre testo.Il testo può essere vuoto, anche se, a vantaggio degli screen reader che sanno leggere le visualizzazioni elenco, sarebbe utile se si aggiornasse il testo con il valore della barra di avanzamento.
Altri suggerimenti
mi piacerebbe prendere uno sguardo al OnDrawItem e completamente ridisegnare il controllo di me stesso.